Android-RegisterForActivityResult的使用与记录,方便后续查看

9 阅读2分钟

Android-RegisterForActivityResult

它是 Android Jetpack 中 Activity Result API 的核心组件,用来替代传统的 startActivityForResult() 和 onActivityResult() 方法。

一、能力:

能力预览.png

常用能力:

  • 页面跳转与数据返回

  • 动态权限申请

  • 媒体操作:拍照、拍视频

  • 文件操作:选择图片、选择视频、打开选择创建文档等

  • 选择联系人

  • 自定义Contract(高级)

二、具体API示例

  1. 页面跳转
//StartActivityForResult-页面跳转与数据返回
val intentActivityResultLauncher = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()
        ) {
            if (it.resultCode == RESULT_OK) {
                val name: String? = it.data?.getStringExtra("name")
                val id: String? = it.data?.getStringExtra("id")
                // 处理返回数据
            }
        }
        
        // 使用方式
        intentActivityResultLauncher.launch(Intent(context, TargetActivity::class.java))
  1. 权限申请
// RequestPermission-单权限申请示例
        val permissionLauncher = registerForActivityResult<String, Boolean>(
            ActivityResultContracts.RequestPermission(),
            ActivityResultCallback { isGranted: Boolean ->
                if (isGranted) {
                    // 权限被授予
                } else {
                    // 权限被拒绝
                }
            }
        )

        // 使用
        permissionLauncher.launch(Manifest.permission.CAMERA)
        
// RequestMultiplePermissions-多权限申请示例
val locationPermissionLauncher = registerForActivityResult(
            ActivityResultContracts.RequestMultiplePermissions(), object :
                ActivityResultCallback<Map<String, Boolean>> {
                override fun onActivityResult(result: Map<String, Boolean>) {
                    // 处理多个权限的申请结果
                    for (entry in result.entries) {
                        val permission = entry.key
                        val isGranted: Boolean = entry.value
                        // 分别处理每个权限的结果
                    }
                }
            })

        // 使用
        locationPermissionLauncher.launch(
            arrayOf<String>(
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION
                )
            )
  1. 拍照
//TakePicturePreview-拍照返回Bitmap预览
private val takePicturePreview =registerForActivityResult(
    ActivityResultContracts.TakePicturePreview()) { bitmap ->
        // 处理返回的Bitmap
        imageView.setImageBitmap(bitmap)
    }
//TakePicture-拍照保存到指定URI
val takePictureLauncher = registerForActivityResult(
        ActivityResultContracts.TakePicture()) { success ->
            if (success) {
                // 图片保存成功
            } else {
                // 图片保存失败
            }
        }
  1. 拍视频
//CaptureVideo-录制视频
val recordVideoLauncher = registerForActivityResult<Uri, Boolean>(
            ActivityResultContracts.CaptureVideo(),
            ActivityResultCallback { success ->
                if (success) {
                    // 视频保存成功
                } else {
                    // 视频保存失败
                }
            }
        )
  1. 选择图片、视频、文件等
//GetContent-选择单个内容
val getContentLauncher = registerForActivityResult<String, Uri?>(
            ActivityResultContracts.GetContent(),
            ActivityResultCallback { uri: Uri? -> 
                if (uri != null) {
                    // 处理选择的图片
                } else {
                    // 用户取消了选择图片
                }
            }
        )

        // 使用-选择图片
        getContentLauncher.launch("image/*")
  1. 选择联系人
//PickContact-选择联系人
val pickContactLauncher = registerForActivityResult<Void?, Uri?>(
            PickContact(),
            ActivityResultCallback { uri: Uri? ->
                if (uri != null) {
                    // 处理选择的联系人
                } else {
                    // 用户取消了选择联系人
                }
            }
        )
  1. 自定义Contract(高级)

如果你经常封装页面跳转,可以自定义:

class MyContract : ActivityResultContract<String, String?>() {

    override fun createIntent(context: Context, input: String): Intent {
        return Intent(context, SecondActivity::class.java).apply {
            putExtra("key", input)
        }
    }

    override fun parseResult(resultCode: Int, intent: Intent?): String? {
        return intent?.getStringExtra("result")
    }
}

注册:

private val myLauncher =
    registerForActivityResult(MyContract()) { result ->
        Log.d("TAG", "返回结果:$result")
    }

三、生产环境的使用场景:

📌 权限管理统一封装,做一个 PermissionHelper (跳转到过往文章)

📌 拍照/选图组件封装,做一个 MediaSelector

📌 页面跳转统一封装

tips:使用注意点

1️⃣ 必须在类成员变量初始化阶段注册;

2️⃣ 不能在 onResume 里注册,因为生命周期已经过了 CREATED;

3️⃣ Fragment中使用时,必须在 Fragment 内注册,而不是 Activity。