使用registerForActivityResult请求权限和拍照

416 阅读2分钟

下面这些预定义的Contract中,除了StartActivityForResult和RequestMultiplePermissions之外,基本都是处理的「与其他APP交互」,返回数据的场景,比如,拍照,选择图片,选择联系人,打开文档等等。使用最多的就是StartActivityForResult和RequestMultiplePermissions了。

  • StartActivityForResult:通用的Contract,不做任何转换,Intent作为输入,ActivityResult作为输出,这也是最常用的一个协定。

  • RequestMultiplePermissions: 用于请求一组权限

  • RequestPermission: 用于请求单个权限

  • TakePicturePreview: 调用MediaStore.ACTION_IMAGE_CAPTURE拍照,返回值为Bitmap图片

  • TakePicture: 调用MediaStore.ACTION_IMAGE_CAPTURE拍照,并将图片保存到给定的Uri地址,返回true表示保存成功。

  • TakeVideo: 调用MediaStore.ACTION_VIDEO_CAPTURE 拍摄视频,保存到给定的Uri地址,返回一张缩略图。

  • PickContact: 从通讯录APP获取联系人

  • GetContent: 提示用选择一条内容,返回一个通过ContentResolver#openInputStream(Uri)访问原生数据的Uri地址(content://形式) 。默认情况下,它增加了Intent#CATEGORY_OPENABLE, 返回可以表示流的内容。

  • CreateDocument: 提示用户选择一个文档,返回一个(file:/http:/content:)开头的Uri。

  • OpenMultipleDocuments: 提示用户选择文档(可以选择多个),分别返回它们的Uri,以List的形式。

  • OpenDocumentTree: 提示用户选择一个目录,并返回用户选择的作为一个Uri返回,应用程序可以完全管理返回目录中的文档。

常规用法

registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
    if (it.resultCode == Activity.RESULT_OK) {
        //it.data
    }
}.launch(Intent(this, ZutaiComponentActivity::class.java))

打开相机拍照

var outputImage = File(this.externalCacheDir, "output_image.jpg")
    if (outputImage.exists()) {
        outputImage.delete()
    }
    outputImage.createNewFile()
    var imageUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        FileProvider.getUriForFile(this, "${BuildConfig.APPLICATION_ID}.fileProvider", outputImage)
    } else {
        Uri.fromFile(outputImage)
    }
    registerForActivityResult(ActivityResultContracts.TakePicture()) {
        if (it) {
            Glide.with(this).load(imageUri).into(bind.image)
        }
    }.launch(imageUri)

打开录像机录像

var outputImage = File(this.externalCacheDir, "output_image.mp4")
    if (outputImage.exists()) {
        outputImage.delete()
    }
    outputImage.createNewFile()
    var imageUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        FileProvider.getUriForFile(this, "${BuildConfig.APPLICATION_ID}.fileProvider", outputImage)
    } else {
        Uri.fromFile(outputImage)
    }
    registerForActivityResult(ActivityResultContracts.TakeVideo()) {
        Glide.with(this).load(imageUri).into(bind.image)
    }.launch(imageUri)

调用文件选择器

mimetype 指定文本文档

registerForActivityResult(ActivityResultContracts.GetContent()){

}.launch("text/plain")

如果需要选择多种文件类型,可以使用OpenDocument

registerForActivityResult(ActivityResultContracts.OpenDocument()){
    Glide.with(this).load(it).into(binding.imageView)
}.launch(arrayOf("image/*","text/plain"))

获取敏感权限

获取一个权限

registerForActivityResult(ActivityResultContracts.RequestPermission()){
   if(it){
       //用户同意了该权限
   }else{
       //用户拒绝了该权限
   }

}.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)

获取多个权限

import android.Manifest
import android.os.Bundle
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val requestMultiplePermissionsLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
            //通过的权限
            val grantedList = permissions.filterValues { it }.mapNotNull { it.key }
            //是否所有权限都通过
            val allGranted = grantedList.size == permissions.size
            val list = (permissions - grantedList).map { it.key }
            //未通过的权限
            val deniedList = list.filter { ActivityCompat.shouldShowRequestPermissionRationale(this, it) }
            //拒绝并且点了“不再询问”权限
            val alwaysDeniedList = list - deniedList

            //处理权限结果,例如更新UI或逻辑
            if (allGranted) {
                // 所有权限都已授予
            } else {
                // 处理未授予的权限
                if (alwaysDeniedList.isNotEmpty()) {
                    // 处理“不再询问”的权限
                }
            }
        }

        // 请求权限
        requestMultiplePermissionsLauncher.launch(arrayOf(
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.CAMERA,
            Manifest.permission.ACCESS_FINE_LOCATION
        ))
    }
}