Android ActivityResultContract使用

Android Activity Results API使用

startActivityForResult问题

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!!)
            }
        }
    }
}

startActivityForResultonActivityResult导致代码嵌套较多、耦合度高、难以维护等问题。

Google可能意识到该问题,推荐使用Activity Results API。

自定义ActivityResultContract

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()
    }
}

系统内置ActivityResultContract

Android系统内置了很多Contract

StartActivityForResult():通用Contract
RequestMultiplePermissions():申请一组权限
RequestPermission():申请单个权限
TakePicturePreview():拍照,返回Bitmap
TakePicture():拍照,保存指定Uri地址,返回true表示保存成功
TakeVideo():拍视频,保存指定Uri地址,返回一张缩略图
PickContact():从通讯录获取联系人
CreateDocument():选择一个文档,返回Uri
OpenDocumentTree():选择一个目录,返回Uri
OpenMultipleDocuments(),选择多个文档,返回多个Uri
OpenDocument():
GetMultipleContents():
GetContent():选择一条内容,返回Uri

StartActivityFoResult

启动一个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")
    }
)

RequestPermission

申请当个权限。

注册协议

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)

RequestMultiplePermissions

申请多个权限。

注册协议

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
    )
)

TakePicturePreview

拍照。

注册协议

private val takePicturePreviewLauncher =
registerForActivityResult(ActivityResultContracts.TakePicturePreview()) {
    
    
    Toast.makeText(mContext, "Bitmap大小:${
      
      it.byteCount}", Toast.LENGTH_SHORT).show()
}

启动

takePicturePreviewLauncher.launch(null)

PickContact

获取指定联系人。

注册协议

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)

源码下载

猜你喜欢

转载自blog.csdn.net/qq_14876133/article/details/120643522