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

Android WebView文件选择器注册Activity Result API报RESUMED错误如何解决

问题修复方案

报错根因

你遇到的报错

Attempting to register while current state is RESUMED

是因为 Activity Result API 强制要求必须在Activity生命周期进入CREATED状态之前完成注册。你将注册逻辑放在了独立文件的伴生对象属性中,触发初始化的时机晚于Activity的onCreate执行阶段,调用相关逻辑时Activity已经处于RESUMED状态,因此触发系统校验报错。

适配改造步骤

1. 调整MainActivity代码,提前完成结果回调注册

将所有Activity Result的注册逻辑移到MainActivity的类成员属性位置,保证在onCreate执行前就完成注册,同时兼容取消选择的边界场景:

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    // 图片选择+拍照统一结果回调
    val imagePickLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        when (result.resultCode) {
            RESULT_OK -> {
                // 优先处理拍照结果,其次处理文件选择结果
                val uri = result.data?.data ?: Global.photoURI
                uri?.let {
                    Global.webView.loadUrl("javascript:showResponse()")
                    Global.filePathCallback?.onReceiveValue(arrayOf(it))
                }
            }
            // 用户取消选择时回传null,避免Web端文件选择器卡住
            RESULT_CANCELED -> Global.filePathCallback?.onReceiveValue(null)
        }
        // 用完清空回调避免内存泄漏
        Global.filePathCallback = null
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Global.context = baseContext
        Global.activity = this
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        Global.webView = binding.webView
        WebListener.initiate()
        WebSettings.setUp()
    }
}

2. 新增Global全局变量存储临时数据

在你的Global单例类中新增两个字段,用于存储Web回调和拍照临时Uri:

object Global {
    // 原有字段保留,新增以下两个字段
    var filePathCallback: ValueCallback<Array<Uri>>? = null
    var photoURI: Uri? = null
}

3. 修改WebListener的onShowFileChooser逻辑

删除原有的直接销毁filePathCallback的代码,先将回调保存到全局:

override fun onShowFileChooser(
    webView: WebView,
    filePathCallback: ValueCallback<Array<Uri>>,
    fileChooserParams: FileChooserParams
): Boolean {
    Util.displayMessage("selected")
    // 保存Web端的文件选择回调
    Global.filePathCallback = filePathCallback
    // 原有权限校验逻辑保留
    if (ContextCompat.checkSelfPermission(
            Global.context,
            Manifest.permission.CAMERA
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        ActivityCompat.requestPermissions(
            Global.activity,
            arrayOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE),
            0
        )
    }
    FileChooser.create()
    return true
}

4. 修改FileChooser的启动逻辑

用MainActivity中提前注册好的Launcher启动选择器,替换原有的startActivity调用:

interface FileChooser {
    companion object {
        fun create() {
            val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
            takePictureIntent.resolveActivity(Global.activity.packageManager)?.also {
                try {
                    Global.photoURI = ImageUri.create()
                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Global.photoURI)
                } catch (ex: Exception) {
                    Util.displayMessage(ex.message.toString())
                }
            }
            val intentArray: Array<Intent?> = arrayOf(takePictureIntent)
            val contentSelectionIntent = Intent(Intent.ACTION_GET_CONTENT).apply {
                addCategory(Intent.CATEGORY_OPENABLE)
                type = "image/*"
            }
            val chooserIntent = Intent(Intent.ACTION_CHOOSER).apply {
                putExtra(Intent.EXTRA_INTENT, contentSelectionIntent)
                putExtra(Intent.EXTRA_TITLE, "Image Chooser")
                putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray)
            }
            // 用提前注册好的launcher启动选择器
            (Global.activity as MainActivity).imagePickLauncher.launch(chooserIntent)
        }
    }
}

5. 清理无用代码

直接删除CamResult.kt和SelectorResult.kt两个文件,原有注册逻辑不符合API要求,不再需要。

可选优化

可以将权限申请逻辑也替换为Activity Result API的RequestPermissions合约实现,替换已废弃的requestPermissions方法,逻辑和上述结果注册逻辑一致,提前在MainActivity中完成注册即可。

内容的提问来源于stack exchange,提问作者Hasan A Yousef

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 11:54:01