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自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1026 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
6月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
826 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
6月前
|
人工智能 前端开发 JavaScript
最佳实践3:用通义灵码开发一款 App
本示例演示使用通义灵码,基于React Native与Node.js开发跨平台类通义App,重点展示iOS端实现。涵盖前端页面生成、后端代码库自动生成、RTK Query通信集成及Qwen API调用全过程,体现灵码在全栈开发中的高效能力。(238字)
710 11
|
6月前
|
移动开发 Android开发
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
305 0
app开发的一些思路
<p><br></p> <p><br></p> <p></p> <h3 style="margin:0px; padding:0px; border:0px; vertical-align:baseline; clear:both; font-weight:normal; list-style:none; color:rgb(102,102,102); font-family:宋体;
3272 0
x3d
小型app开发的思路
前提: 1. 性能不是最重要; 2. 人手少; 3. 速度要快;   结论: 1. 混合式 2. 减少app的复杂程度 3. 追求性能   (博客,尽量让自己每天写一点,短一点都可以)
x3d
658 0
|
6月前
|
缓存 移动开发 JavaScript
如何优化UniApp开发的App的启动速度?
如何优化UniApp开发的App的启动速度?
1081 139
|
6月前
|
移动开发 JavaScript weex
UniApp开发的App在启动速度方面有哪些优势和劣势?
UniApp开发的App在启动速度方面有哪些优势和劣势?
518 137
|
6月前
|
数据采集 JavaScript 前端开发
开发比分App?你缺的不是程序员
开发体育比分App,关键不在代码,而在懂体育、懂数据、懂用户。明确定位、理清需求、选好数据源,再找专业的产品、数据与技术人才协同,才能少走弯路。程序员最后入场,效率最高。
335 154