引言
在以前,我们经常会遇到启动一个 Activity,并从中获取数据的需求,此外还有一些常见的场景是调用系统相机、调用相册获取照片、调用通讯录等。通常的做法就是使用 Intent 携带数据,之后将 Intent 和请求码传入 startActivityForResult
方法来启动下一个Activity。
但是随着应用的开发 onActivityResult 回调方法难以解耦复用,后期维护困难。于是Google推出Activity Results API
Activity Results API介绍
Activity Results API 是 Google官方推荐的Activity、Fragment获取数据的方式。它有两个主要的用途:
- 取代 startActivityForResult 方法,去启动Activity并返回结果
- 取代 requestPermissions 方法,去请求运行时权限
========================================================================
在 AppCompatActivity 或者 Fragment 中使用 registerForActivityResult() 方法来代替 startActivityForResult() (Android api29中使用startActivityForResult提示已过时,应该变成registerForActivityResult)。
该方法接收两个参数并返回ActivityResultLauncher。
一个是ActivityResultContract,
一个是ActivityResultCallback。
最终使用 activityResultLauncher 调用launch(...)
启动目标Activity。
ActivityResultLauncher
用于启动另一个 ActivityActivityResultContract
这是一个协议类,它的两个泛型分别表示启动参数的类型和返回结果的类型。可以通过继承的方式来自定义 ActivityResultContractActivityResultCallback
是单一方法接口,内部只有 onActivityResult 这一个方法,可以接受ActivityResultContract 中定义的输出类型的对象
【注意】:registerForActivityResult只能在onCreate中注册。onstart之后就不能注册了
打开activity
示例:
val activityResultLauncher = registerForActivityResult(StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
//获取返回的结果
val data = result.data!!.getStringExtra("data")
Log.d( "tag", "onCreate: $data")
Toast.makeText(this, data, Toast.LENGTH_SHORT).show()
}
}
val intent = Intent(this@MainActivity, SecondActivity::class.java)
activityResultLauncher.launch(intent)
申请权限
示例:
//单个权限
registerForActivityResult(ActivityResultContracts.RequestPermission()){
if(it){
//用户同意了该权限
}else{
//用户拒绝了该权限
}
}.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
// 多个权限
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()){it->
//通过的权限
val grantedList = it.filterValues { it }.mapNotNull { it.key }
//是否所有权限都通过
val allGranted = grantedList.size == it.size
val list = (it - grantedList).map { it.key }
//未通过的权限
val deniedList = list.filter { ActivityCompat.shouldShowRequestPermissionRationale(this, it) }
//拒绝并且点了“不再询问”权限
val alwaysDeniedList = list - deniedList
}.launch(arrayOf("权限1","权限2","权限3"))
其他操作
除了基本用法,ActivityResultContracts还提供了一些ActivityResultContract的实现类,以便进行其他的操作: