Android-RegisterForActivityResult
它是 Android Jetpack 中 Activity Result API 的核心组件,用来替代传统的 startActivityForResult() 和 onActivityResult() 方法。
一、能力:
常用能力:
页面跳转与数据返回
动态权限申请
媒体操作:拍照、拍视频
文件操作:选择图片、选择视频、打开选择创建文档等
选择联系人
自定义Contract(高级)
二、具体API示例
- 页面跳转
//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))
- 权限申请
// 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
)
)
- 拍照
//TakePicturePreview-拍照返回Bitmap预览
private val takePicturePreview =registerForActivityResult(
ActivityResultContracts.TakePicturePreview()) { bitmap ->
// 处理返回的Bitmap
imageView.setImageBitmap(bitmap)
}
//TakePicture-拍照保存到指定URI
val takePictureLauncher = registerForActivityResult(
ActivityResultContracts.TakePicture()) { success ->
if (success) {
// 图片保存成功
} else {
// 图片保存失败
}
}
- 拍视频
//CaptureVideo-录制视频
val recordVideoLauncher = registerForActivityResult<Uri, Boolean>(
ActivityResultContracts.CaptureVideo(),
ActivityResultCallback { success ->
if (success) {
// 视频保存成功
} else {
// 视频保存失败
}
}
)
- 选择图片、视频、文件等
//GetContent-选择单个内容
val getContentLauncher = registerForActivityResult<String, Uri?>(
ActivityResultContracts.GetContent(),
ActivityResultCallback { uri: Uri? ->
if (uri != null) {
// 处理选择的图片
} else {
// 用户取消了选择图片
}
}
)
// 使用-选择图片
getContentLauncher.launch("image/*")
- 选择联系人
//PickContact-选择联系人
val pickContactLauncher = registerForActivityResult<Void?, Uri?>(
PickContact(),
ActivityResultCallback { uri: Uri? ->
if (uri != null) {
// 处理选择的联系人
} else {
// 用户取消了选择联系人
}
}
)
- 自定义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。