startActivityForResult(Intent(this, SecondActivity::class.java), REQ_CODE)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQ_CODE) {
if (resultCode == Activity.RESULT_OK) {
data?.let {
val value: String? = data.getStringExtra("hello")
log(value!!)
}
}
}
}
startActivityForResult
和onActivityResult
导致代码嵌套较多、耦合度高、难以维护等问题。
Google可能意识到该问题,推荐使用Activity Results API。
Activity Results API有两个重要的类:
ActivityResultContract
:协议,这是一个抽象类,定义如何传递数据和如何接收数据,ActivityResultLauncher
:启动器,相当于以前的startActivity()
class MyContract : ActivityResultContract<String, String>() {
override fun createIntent(context: Context, input: String?): Intent {
return Intent(context, SecondActivity::class.java).apply {
putExtra("name", input)
}
}
override fun parseResult(resultCode: Int, intent: Intent?): String? {
val result = intent?.getStringExtra("result")
return if (resultCode == Activity.RESULT_OK) {
result
} else {
null
}
}
}
private val launcher = registerForActivityResult(MyContract()) {
textView.text = it
}
launcher.launch("hello world")
SecondActivity
class SecondActivity : AppCompatActivity() {
private lateinit var textView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
textView = findViewById(R.id.textView)
val name = intent.getStringExtra("name")
textView.text = name
}
fun finishClick(view: View) {
setResult(Activity.RESULT_OK, Intent().apply {
putExtra("result", "hello ActivityResult")
})
finish()
}
}
Android系统内置了很多Contract
StartActivityForResult():通用Contract
RequestMultiplePermissions():申请一组权限
RequestPermission():申请单个权限
TakePicturePreview():拍照,返回Bitmap
TakePicture():拍照,保存指定Uri地址,返回true表示保存成功
TakeVideo():拍视频,保存指定Uri地址,返回一张缩略图
PickContact():从通讯录获取联系人
CreateDocument():选择一个文档,返回Uri
OpenDocumentTree():选择一个目录,返回Uri
OpenMultipleDocuments(),选择多个文档,返回多个Uri
OpenDocument():
GetMultipleContents():
GetContent():选择一条内容,返回Uri
启动一个Activity并返回数据。
注册协议
private val activityLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK) {
val data = it.data
data?.apply {
val name = getStringExtra("name")
val age = getIntExtra("age", 0)
val address = getStringExtra("address")
textView.text = "name:$name age:$age address:$address"
}
}
}
启动
activityLauncher.launch(
Intent(this, ThirdActivity::class.java).apply {
putExtra("name", "小花")
putExtra("age", 38)
putExtra("address", "guangzhou")
}
)
申请当个权限。
注册协议
private val permissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) {
if (it) {
Toast.makeText(mContext, "权限申请-成功", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(mContext, "权限申请-失败", Toast.LENGTH_SHORT).show()
}
}
启动
permissionLauncher.launch(Manifest.permission.CAMERA)
申请多个权限。
注册协议
private val multiPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
it ->
it.forEach {
if (it.value) {
Toast.makeText(mContext, "${it.key} 申请权限-成功", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(mContext, "${it.key} 申请权限-失败", Toast.LENGTH_SHORT).show()
}
}
}
启动
multiPermissionLauncher.launch(
arrayOf<String>(
Manifest.permission.CAMERA,
Manifest.permission.CALL_PHONE,
Manifest.permission.ACCESS_FINE_LOCATION
)
)
拍照。
注册协议
private val takePicturePreviewLauncher =
registerForActivityResult(ActivityResultContracts.TakePicturePreview()) {
Toast.makeText(mContext, "Bitmap大小:${it.byteCount}", Toast.LENGTH_SHORT).show()
}
启动
takePicturePreviewLauncher.launch(null)
获取指定联系人。
注册协议
private val pickContactLauncher =
registerForActivityResult(ActivityResultContracts.PickContact()) {
it ->
val cursor: Cursor? = mContext.getContentResolver().query(it, null, null, null, null)
cursor?.let {
it ->
val builder = StringBuilder()
while (cursor.moveToNext()) {
//联系人id
val contactId: String =
cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID))
//联系人姓名
val contackName: String =
cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))
builder.append("联系人id:$contactId \n")
.append("联系人姓名:$contackName \n")
val phones = contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId,
null, null
)
phones?.let {
it ->
while (it.moveToNext()) {
val phoneNumber: String =
it.getString(it.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
builder.append("联系人手机号:$phoneNumber \n")
}
it.close()
}
}
it.close()
UiUtils.showDialog(builder.toString(), mContext)
}
}
启动
pickContactLauncher.launch(null)