优雅调用系统相机,版本兼容

调用系统相机拍摄并存储

val REQUEST_CODE_TAKE_PHOTO = 1
val REQUEST_CODE_SELECT_PHOTO = 2
    lateinit var imageUri : Uri
    lateinit var outputImage : File

    private fun takePhoto(){
        //Android10.0开始,sd卡不能直接访问,而是通过作用域存储,也就是应用关联缓存目录
        outputImage = File(externalCacheDir,"myPhoto.jpg")
        if (outputImage.exists()){
            outputImage.delete()
        }
        outputImage.createNewFile()
        imageUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
            //当Android7.0开始,直接使用本地真是路径的Uri被认为是不安全的,
            //会抛出一个FileUriExposeException异常,需要通过FileProvider来获取
            FileProvider.getUriForFile(this,"com.example.test.fileprovider",outputImage)
        }else{
            Uri.fromFile(outputImage)
        }
        val intent = Intent("android.media.action.IMAGE_CAPTURE")
        intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri)
        startActivityForResult(intent,REQUEST_CODE_TAKE_PHOTO)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when(requestCode){
            REQUEST_CODE_TAKE_PHOTO ->{
                if (resultCode == Activity.RESULT_OK){
                    //拍摄的图片bitmap对象
                    val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(imageUri))
                    //获取一个正立的bitmap对象
                    checkRotate(bitmap)
                }
            }
        }
    }

    /**
     * 判断图片是否经过旋转
     */
    private fun checkRotate(bitmap: Bitmap) : Bitmap{
        val exif = ExifInterface(outputImage.path)
        val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL)
        return when(orientation){
            ExifInterface.ORIENTATION_ROTATE_90 -> rotateBitmap(bitmap,90)
            ExifInterface.ORIENTATION_ROTATE_180 -> rotateBitmap(bitmap,180)
            ExifInterface.ORIENTATION_ROTATE_270 -> rotateBitmap(bitmap,270)
            else -> bitmap
        }
    }

    /**
     * 旋转图片
     */
    private fun rotateBitmap(bitmap: Bitmap, degree: Int) : Bitmap {
        val matrix = Matrix()
        matrix.postRotate(degree.toFloat())
        val newBitmap = Bitmap.createBitmap(bitmap,0,0,bitmap.width,bitmap.height,matrix,true)
        bitmap.recycle()
        return newBitmap
    }


由于使用到FileProvider,还需进行如下配置,在AndroidManifest.xml 的application标签内


            
        

android:authorities的值必须和FileProvider.getUriForFile方法的第二参数一致。
然后还需要在res目录创建xml文件夹,并在此添加file_paths.xml


    

name值可以随便填,path这里用单斜线表示整个sd卡进行共享

另外,选择手机图片

//打开文件选择器
        val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
        intent.addCategory(Intent.CATEGORY_OPENABLE)
        //指定只显示图片
        intent.type = "image/*"
        startActivityForResult(intent,REQUEST_CODE_SELECT_PHOTO)


override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when(requestCode){
            REQUEST_CODE_TAKE_PHOTO ->{
                if (resultCode == Activity.RESULT_OK && data != null){
                    data.data?.let{ uri ->
                        val bitmap = contentResolver.openFileDescriptor(uri,"r")?.use{
                            BitmapFactory.decodeFileDescriptor(it.fileDescriptor)
                        }
                    }
                }
            }
        }
    }

你可能感兴趣的:(优雅调用系统相机,版本兼容)