You need to enable JavaScript to run this app. Fragment中已废弃startActivityForResult的替换方案及相关疑问咨询
优惠活动
大模型
产品
解决方案
定价
更多

Fragment中已废弃startActivityForResult的替换方案及相关疑问咨询

Fragment场景下startActivityForResult废弃适配方案

一、废弃API适配修改方案

AndroidX Activity 1.2.0 和 Fragment 1.3.0 之后官方推出Activity Result API替换已废弃的startActivityForResult(),针对你给出的拍照场景适配步骤如下:

  1. 移除原来的常量请求码REQUEST_PHOTO,改用注册启动器的方式接收返回结果
  2. 在Fragment中提前注册启动器,处理拍照完成后的回调逻辑
  3. 点击事件中将startActivityForResult()替换为启动器的launch()方法

修改后完整示例代码

class ExampleFragment:Fragment(), DatePickerFragment.Callbacks {
    private lateinit var photoUri : Uri
    // 注册拍照结果启动器
    private val takePhotoLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess ->
        if (isSuccess) {
            // 这里写原来onActivityResult里REQUEST_PHOTO请求码对应的处理逻辑
            // 拍照成功,photoUri里已经有写入的照片数据
        } else {
            // 拍照取消/失败处理
        }
    }

    override fun onStart() {
        super.onStart()
        photoButton.apply {
            val packageManager : PackageManager = requireActivity().packageManager
            val captureImage = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
            val resolvedActivity : ResolveInfo? =
                packageManager.resolveActivity(captureImage,
                PackageManager.MATCH_DEFAULT_ONLY)
            if (resolvedActivity == null) {
                isEnabled = false
            }
            setOnClickListener {
                val cameraActivities : List<ResolveInfo> =
                    packageManager.queryIntentActivities(captureImage, PackageManager.MATCH_DEFAULT_ONLY)
                for (cameraActivity in cameraActivities) {
                    requireActivity().grantUriPermission(
                        cameraActivity.activityInfo.packageName,photoUri,
                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                    )
                }
                // 替换原来的startActivityForResult
                takePhotoLauncher.launch(photoUri)
            }
        }
    }
}

如果你需要自定义Intent而不用封装好的TakePicture契约,也可以用ActivityResultContracts.StartActivityForResult()契约:

// 注册通用启动器
private val customLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        val data = result.data
        // 处理返回结果
    }
}
// 调用时传入自定义intent
customLauncher.launch(captureImage)

二、「从Fragment所属宿主Activity调用Activity.startActivityForResult(Intent, int)」的含义

这个描述指的是你在Fragment中不调用Fragment自身的startActivityForResult()方法,而是调用requireActivity().startActivityForResult(intent, requestCode)的写法。
这种写法下,请求的发起方是宿主Activity而非当前Fragment,后续返回结果只会回调到宿主Activity的onActivityResult()方法中,不会分发到当前Fragment的onActivityForResult(),此前这是一个常见的使用误区。

三、简明操作指引

  • 确保依赖版本符合要求:项目依赖的AndroidX Fragment版本≥1.3.0,Activity版本≥1.2.0
  • 提前注册结果启动器:不要在点击事件等执行逻辑中才注册,必须在Fragment生命周期走到onAttach之前完成注册(直接写在成员变量位置即可)
  • 完全替换旧API:废弃的startActivityForResult()和onActivityResult()直接删除,全逻辑改用Activity Result API
  • 不要混用发起方:如果需要结果回调到Fragment,永远调用Fragment自身的启动器launch()方法,不要通过宿主Activity发起页面跳转请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 12:36:03