Android Activity Result API 使用

本文介绍了在Android应用中如何使用新的ActivityResult API进行页面跳转和权限申请。通过示例代码展示了如何实现普通的页面跳转,以及如何使用registerForActivityResult请求单个和多个权限。同时,详细列举了预定义的Contract,如StartActivityForResult、RequestMultiplePermissions等,这些Contract简化了与其他应用交互的过程,如拍照、选择联系人、打开文档等。

1.在app下的build.gradle引入:

implementation 'androidx.activity:activity:1.2.0-beta01'
implementation 'androidx.fragment:fragment:1.3.0-beta01'

2.页面普通跳转(原startActivityForResult)

(1)第一个页面:

class MainActivity : AppCompatActivity() {

    private lateinit var textview: TextView

    private val myActivityLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult->
            if (activityResult.resultCode == RESULT_OK){
                val result = activityResult.data?.getStringExtra("result")
                textview.text = "回传数据:$result"
            }

        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        textview = findViewById(R.id.textview)
        findViewById<Button>(R.id.button).setOnClickListener {
            val intent = Intent(this, SecondActivity::class.java).apply {
                putExtra("name", "第一个页面传递的数据")
            }
            myActivityLauncher.launch(intent)

        }
    }
    
}

(2)第二个页面:

class SecondActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
        val textView = findViewById<TextView>(R.id.textview)

        val name = intent.getStringExtra("name")
        textView.text = "接收数据:$name"
        textView.setOnClickListener {
            val intent = Intent().apply {
                putExtra("result", "第二个页面回传数据")
            }
            setResult(RESULT_OK, intent)
            finish()
        }
    }
}

(3)效果:

第二个页面:
第二个页面接收

第一个页面:
在这里插入图片描述

3.权限申请:

class MainActivity : AppCompatActivity() {

    private lateinit var textview: TextView

    private val myActivityLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult ->
            if (activityResult.resultCode == RESULT_OK) {
                val result = activityResult.data?.getStringExtra("result")
                textview.text = "回传数据:$result"
            }

        }

    //请求单个权限
    private val requestOnePermission =
        registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
            if (isGranted) Toast.makeText(this, "权限已授予", Toast.LENGTH_SHORT).show()
            else Toast.makeText(this, "权限被拒绝", Toast.LENGTH_SHORT).show()

        }

    //请求一组权限
    private val requestMultiplePermissions =
        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions: Map<String, Boolean> ->
            if (permissions.entries.any { !it.value }){
                Toast.makeText(this, "权限被拒绝", Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(this, "权限已授予", Toast.LENGTH_SHORT).show()
            }
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        textview = findViewById(R.id.textview)
        findViewById<Button>(R.id.button).setOnClickListener {
            val intent = Intent(this, SecondActivity::class.java).apply {
                putExtra("name", "第一个页面传递的数据")
            }
            myActivityLauncher.launch(intent)
        }

        findViewById<Button>(R.id.button1).setOnClickListener {
            requestOnePermission.launch(Manifest.permission.CAMERA)
        }

        findViewById<Button>(R.id.button2).setOnClickListener {
            requestMultiplePermissions.launch(
                arrayOf(
                    Manifest.permission.CAMERA,
                    Manifest.permission.RECORD_AUDIO,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
                )
            )
        }
    }

}

4. 预定义的Contract

StartActivityForResult()
RequestMultiplePermissions()
RequestPermission()
TakePicturePreview()
TakePicture()
TakeVideo()
PickContact()
CreateDocument()
OpenDocumentTree()
OpenMultipleDocuments()
OpenDocument()
GetMultipleContents()
GetContent()
StartActivityForResult: 通用的Contract,不做任何转换,Intent作为输入,ActivityResult作为输出,这也是最常用的一个协定。

  • RequestMultiplePermissions: 用于请求一组权限
  • RequestPermission: 用于请求单个权限
  • TakePicturePreview: 调用MediaStore.ACTION_IMAGE_CAPTURE拍照,返回值为Bitmap图片
  • TakePicture: 调用MediaStore.ACTION_IMAGE_CAPTURE拍照,并将图片保存到给定的Uri地址,返回true表示保存成功。
  • TakeVideo: 调用MediaStore.ACTION_VIDEO_CAPTURE 拍摄视频,保存到给定的Uri地址,返回一张缩略图。
  • PickContact: 从通讯录APP获取联系人
  • GetContent: 提示用选择一条内容,返回一个通过ContentResolver#openInputStream(Uri)访问原生数据的Uri地址(content://形式) 。默认情况下,它增加了 Intent#CATEGORY_OPENABLE, 返回可以表示流的内容。
  • CreateDocument: 提示用户选择一个文档,返回一个(file:/http:/content:)开头的Uri。
  • OpenMultipleDocuments: 提示用户选择文档(可以选择多个),分别返回它们的Uri,以List的形式。
  • OpenDocumentTree: 提示用户选择一个目录,并返回用户选择的作为一个Uri返回,应用程序可以完全管理返回目录中的文档。

上面这些预定义的Contract中,除了StartActivityForResult和RequestMultiplePermissions之外,基本都是处理的与其他APP交互,返回数据的场景,比如,拍照,选择图片,选择联系人,打开文档等等。使用最多的就是StartActivityForResult和RequestMultiplePermissions了。

<think>我们参考用户提供的引用内容,特别是引用[1]和引用[4]与问题直接相关。用户的问题:如何在Android使用ResultAPI,并请求示例代码。根据引用[1]:ActivityResultAPI包含两个主要方法:-createIntent():创建一个用于startActivityForResult的Intent-parseResult():对onActivityResult的结果进行转换此外,我们知道在Android中,使用ActivityResultAPI可以避免在Activity中重写onActivityResult方法,而是通过注册一个ActivityResultLauncher来启动活动并处理结果。步骤:1.Activity/Fragment中注册一个ActivityResultContract(系统预定义或自定义)和对应的回调处理。2.使用注册返回的ActivityResultLauncher来启动活动。3.在回调中处理结果。示例代码(使用预定义的合约,例如启动活动并获取结果):假设我们想要启动一个活动来获取文本内容(例如,从另一个活动返回一个字符串),我们可以使用预定义的合约ActivityResultContracts.StartActivityForResult。但是,更具体的例子:我们可以使用ActivityResultContracts.Pick来选择一个图片,然后显示在ImageView中。根据引用[4]中有一个布局文件,其中包含一个Button和一个ImageView,我们可以用这个布局来实现选择图片并显示的功能。下面我们结合引用[1]和引用[4]来写一个示例:步骤1:在Activity中注册一个ActivityResultLauncher步骤2:设置按钮点击事件,使用这个launcher启动选择图片的Intent步骤3:在回调中处理返回的Uri,并设置到ImageView上示例代码:首先,确保在AndroidManifest.xml中添加必要的权限(如果从外部存储选择图片,需要READ_EXTERNAL_STORAGE权限,但注意Android10以后可能需要使用MediaStore,并且权限策略有变化,这里为了示例简化,假设我们使用ActivityResultContracts.Pick,它不需要直接请求权限,因为系统会处理)。然后,在Activity中:</think> ### Android Activity Result API 使用示例 在 Android 中,Activity Result API 提供了更清晰的方式处理活动间通信,避免了传统的 `onActivityResult()` 回调。以下是完整实现代码: ```kotlin // MainActivity.kt class MainActivity : AppCompatActivity() { // 1. 声明结果启动器 private lateinit var getContent: ActivityResultLauncher<String> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 2. 注册结果合约 getContent = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? -> // 3. 处理结果 uri?.let { findViewById<ImageView>(R.id.img).setImageURI(uri) } } // 4. 触发选择操作 findViewById<Button>(R.id.get_content).setOnClickListener { getContent.launch("image/*") // 指定MIME类型 } } } ``` ```xml <!-- activity_main.xml --> <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <Button android:id="@+id/get_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Select Image" /> <ImageView android:id="@+id/img" android:layout_width="300dp" android:layout_height="300dp" android:layout_marginTop="24dp" android:scaleType="centerCrop" /> </LinearLayout> ``` ### 核心组件解析: 1. **ActivityResultContracts** - `GetContent()`: 文件选择合约[^1] - `TakePicture()`: 拍照合约 - `RequestPermission()`: 权限请求合约 - 自定义合约需实现 `createIntent()` 和 `parseResult()` 2. **ActivityResultLauncher** - 通过 `registerForActivityResult()` 注册 - 使用 `launch()` 触发操作并传递参数 3. **结果处理** - 在 lambda 表达式中直接获取类型化结果(本例中为 `Uri?`) - 无需处理 `requestCode` 和 `resultCode`[^1] ### 优势对比传统方式: | 传统方式 | Result API | |---------|-----------| | 需要重写 `onActivityResult()` | 逻辑隔离更清晰 | | 请求码易冲突 | 无请求码管理 | | 结果处理分散 | 结果集中处理 | | 类型转换复杂 | 自动类型安全 | > ⚠️ **注意**:此 API 需要添加依赖: ```gradle dependencies { implementation "androidx.activity:activity-ktx:1.6.0" implementation "androidx.fragment:fragment-ktx:1.5.5" } ```
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值