You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android开发:如何为多个ActivityResultLauncher创建选择器?

Android 多意图选择器适配Activity Result API 通用实现方案

这是目前行业内的常规实现方式,迁移成本极低,可完全对齐原有逻辑:

核心思路

无需为每个操作单独注册ActivityResultLauncher,直接复用系统提供的ActivityResultContracts.StartActivityForResult通用合约,原有Intent.createChooser构建选择器的逻辑不需要做任何修改,仅将回调处理从宿主的onActivityResult方法迁移到Launcher的回调中即可。

实现步骤

1. 预注册通用Launcher

必须在Activity/Fragment的onCreate生命周期阶段完成注册,不能在点击事件触发时动态注册:

private val mediaChooserLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        val resultData = result.data
        // 此处处理返回结果的逻辑和原有onActivityResult中的实现完全一致
        resultData?.data?.let { mediaUri ->
            // 业务层处理拿到的媒体Uri
            processUploadMedia(mediaUri)
        }
    }
}

2. 构建并启动选择器

和原有Intent.createChooser的构建逻辑完全一致:

fun openMediaUploadChooser() {
    // 构建本地媒体选择意图
    val localMediaIntent = Intent(Intent.ACTION_GET_CONTENT).apply {
        type = "*/*"
        putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("image/*", "video/*"))
    }
    // 构建相机拍摄类意图
    val cameraIntents = mutableListOf<Intent>()
    val takePhotoIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    val takeVideoIntent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
    cameraIntents.add(takePhotoIntent)
    cameraIntents.add(takeVideoIntent)
    // 组装系统选择器
    val chooser = Intent.createChooser(localMediaIntent, "请选择上传方式")
    chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toTypedArray())
    // 启动选择器
    mediaChooserLauncher.launch(chooser)
}

可选优化方案

如果需要自定义选择器的UI样式,不使用系统原生Chooser,可采用以下实现:

  • 自定义弹窗列出「选择本地文件」「拍照」「拍视频」等选项
  • 为每个操作单独注册对应专属ActivityResultLauncher,比如TakePicture、PickVisualMedia等系统预置合约
  • 用户点击弹窗对应选项时,触发对应Launcher的launch方法即可

内容的提问来源于stack exchange,提问作者AppLover

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 04:45:10