kotlin开发安卓app,使用webivew 触发 onShowFileChooser, 但只能触发一次,第二次无法触发,是怎么回事。 如何解决

简介: 在Android WebView开发中,`onShowFileChooser`方法用于开启文件选择。当用户只能选择一次文件可能是因为未正确处理选择回调。解决此问题需确保:1) 实现`WebChromeClient`并覆写`onShowFileChooser`;2) 用户选择文件后调用`ValueCallback.onReceiveValue`传递URI;3) 传递结果后将`ValueCallback`设为`null`以允许再次选择。下面是一个Kotlin示例,展示如何处理文件选择和结果回调。别忘了在Android 6.0+动态请求存储权限,以及在Android 10+处理分区存储。

在使用WebView开发Android应用时,onShowFileChooser方法通常用于允许用户从设备中选择文件。如果这个方法只能被触发一次,问题可能在于没有正确处理文件选择的回调结果。在WebView中,onShowFileChooser方法需要一个ValueCallback<Uri[]>作为参数,用于接收文件选择的结果。如果你没有正确地调用ValueCallback来传递结果,系统可能不会允许你再次触发文件选择器。

解决这个问题的关键在于确保你正确地处理了文件选择的结果,并且在文件选择完成后释放了ValueCallback。以下是一个典型的解决方案:

  1. 确保你有正确的WebChromeClient实现:
    在你的Activity中,确保你已经覆盖了WebChromeClientonShowFileChooser方法。
  2. 正确处理文件选择结果:
    当用户选择了一个文件并返回时,你需要调用ValueCallbackonReceiveValue方法来传递所选文件的Uri数组。
  3. 重置ValueCallback:
    一旦你传递了结果,记得将ValueCallback设置为null,这样系统才能知道可以选择另一个文件。

以下是一个具体的示例代码:


class MainActivity : AppCompatActivity(), ValueCallback<Array<Uri>> {

    private var mUploadMessage: ValueCallback<Array<Uri>>? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val webView = findViewById<WebView>(R.id.webView)
        webView.webViewClient = WebViewClient()
        webView.webChromeClient = object : WebChromeClient() {
            override fun onShowFileChooser(
                window: Window?,
                filePathCallback: ValueCallback<Array<Uri>>?,
                fileChooserParams: FileChooserParams?
            ): Boolean {
                if (mUploadMessage != null) {
                    mUploadMessage = null
                }

                mUploadMessage = filePathCallback

                // 启动文件选择器
                val intent = fileChooserParams?.createIntent()
                startActivityForResult(intent, FILECHOOSER_RESULT_CODE)

                return true
            }
        }

        // 加载网页
        webView.loadUrl("https://example.com")
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if (requestCode == FILECHOOSER_RESULT_CODE) {
            if (mUploadMessage == null) {
                return
            }

            when (resultCode) {
                Activity.RESULT_OK -> {
                    // 从data Intent中获取Uri
                    val result = if (data == null || data.data == null) {
                        arrayOfNulls<Uri>(0)
                    } else {
                        data.clipData?.let { clipData ->
                            Array(clipData.itemCount) { i ->
                                clipData.getItemAt(i).uri
                            }
                        } ?: arrayOf(data.data!!)
                    }

                    mUploadMessage!!.onReceiveValue(result)
                    mUploadMessage = null
                }
                Activity.RESULT_CANCELED -> {
                    mUploadMessage!!.onReceiveValue(null)
                    mUploadMessage = null
                }
            }
        }
    }

    override fun onReceiveValue(result: Array<Uri>?) {
        // 这里不应该有代码,因为我们只需要传递结果给WebView,而不是处理结果
    }

    companion object {
        private const val FILECHOOSER_RESULT_CODE = 1
    }
}


在上面的代码中,onShowFileChooser方法被重写,以处理文件选择的启动。onActivityResult方法则负责处理文件选择的结果,并通过onReceiveValue方法将结果传递给WebView。

记住,在处理文件选择时,你可能需要考虑权限问题,特别是从Android 6.0(API级别23)开始,你需要动态请求存储权限。如果在Android 10(API级别29)及以上版本,你可能需要额外处理分区存储的影响。

相关文章
|
6月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1099 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
6月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
860 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
6月前
|
人工智能 前端开发 JavaScript
最佳实践3:用通义灵码开发一款 App
本示例演示使用通义灵码,基于React Native与Node.js开发跨平台类通义App,重点展示iOS端实现。涵盖前端页面生成、后端代码库自动生成、RTK Query通信集成及Qwen API调用全过程,体现灵码在全栈开发中的高效能力。(238字)
739 11
|
6月前
|
移动开发 Android开发
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
318 0
|
存储 缓存 安全
Android14 适配之——现有 App 安装到 Android14 手机上需要注意些什么?
Android14 适配之——现有 App 安装到 Android14 手机上需要注意些什么?
1314 0
|
传感器 物联网 Android开发
【Android App】物联网中查看手机支持的传感器及实现摇一摇功能-加速度传感器(附源码和演示 超详细)
【Android App】物联网中查看手机支持的传感器及实现摇一摇功能-加速度传感器(附源码和演示 超详细)
710 1
|
Android开发 网络架构
【Android App】检查手机连接WiFi信息以及扫描周围WiFi的讲解及实战(附源码和演示 超详细必看)
【Android App】检查手机连接WiFi信息以及扫描周围WiFi的讲解及实战(附源码和演示 超详细必看)
2249 1
|
XML 安全 Java
Android Studio App开发之广播组件Broadcast的讲解及实战(包括收发标准、有序、静态广播实现手机震动功能 附源码)
Android Studio App开发之广播组件Broadcast的讲解及实战(包括收发标准、有序、静态广播实现手机震动功能 附源码)
1198 0
|
XML Java 定位技术
【Android App】定位导航GPS中开启手机定位功能讲解及实战(附源码和演示 超详细)
【Android App】定位导航GPS中开启手机定位功能讲解及实战(附源码和演示 超详细)
1580 0
|
XML Java Android开发
Android App开发手机阅读中实现平滑翻书效果和卷曲翻书动画实战(附源码 简单易懂 可直接使用)
Android App开发手机阅读中实现平滑翻书效果和卷曲翻书动画实战(附源码 简单易懂 可直接使用)
1183 0
下一篇
开通oss服务