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)及以上版本,你可能需要额外处理分区存储的影响。

相关文章
|
23天前
|
Android开发 数据安全/隐私保护 开发者
Android自定义view之模仿登录界面文本输入框(华为云APP)
本文介绍了一款自定义输入框的实现,包含静态效果、hint值浮动动画及功能扩展。通过组合多个控件完成界面布局,使用TranslateAnimation与AlphaAnimation实现hint文字上下浮动效果,支持密码加密解密显示、去除键盘回车空格输入、光标定位等功能。代码基于Android平台,提供完整源码与attrs配置,方便复用与定制。希望对开发者有所帮助。
|
24天前
|
存储 消息中间件 前端开发
PHP后端与uni-app前端协同的校园圈子系统:校园社交场景的跨端开发实践
校园圈子系统校园论坛小程序采用uni-app前端框架,支持多端运行,结合PHP后端(如ThinkPHP/Laravel),实现用户认证、社交关系管理、动态发布与实时聊天功能。前端通过组件化开发和uni.request与后端交互,后端提供RESTful API处理业务逻辑并存储数据于MySQL。同时引入Redis缓存热点数据,RabbitMQ处理异步任务,优化系统性能。核心功能包括JWT身份验证、好友系统、WebSocket实时聊天及活动管理,确保高效稳定的用户体验。
99 3
PHP后端与uni-app前端协同的校园圈子系统:校园社交场景的跨端开发实践
|
16天前
|
安全 Java Android开发
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
43 0
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
|
1月前
|
人工智能 JavaScript 前端开发
借助 CodeBuddy,我轻松开发出三分钟读书 App
借助 CodeBuddy,我轻松开发出三分钟读书 App
46 6
|
1月前
|
人工智能 小程序 API
【一步步开发AI运动APP】九、自定义姿态动作识别检测——之关键点追踪
本文介绍了【一步步开发AI运动APP】系列中的关键点追踪技术。此前分享的系列博文助力开发者打造了多种AI健身场景的小程序,而新系列将聚焦性能更优的AI运动APP开发。文章重点讲解了“关键点位变化追踪”能力,适用于动态运动(如跳跃)分析,弥补了静态姿态检测的不足。通过`pose-calc`插件,开发者可设置关键点(如鼻子)、追踪方向(X或Y轴)及变化幅度。示例代码展示了如何在`uni-app`框架中使用`createPointTracker`实现关键点追踪,并结合人体识别结果完成动态分析。具体实现可参考文档与Demo示例。
|
2月前
|
人工智能 小程序 API
【一步步开发AI运动APP】八、自定义姿态动作识别检测——之姿态相似度比较
本文介绍了如何通过姿态相似度比较技术简化AI运动应用开发。相比手动配置规则,插件`pose-calc`提供的姿态相似度比较器可快速评估两组人体关键点的整体与局部相似度,降低开发者工作量。文章还展示了在`uni-app`框架下调用姿态比较器的示例代码,并提供了桌面辅助工具以帮助提取标准动作样本,助力开发者打造性能更优、体验更好的AI运动APP。
|
2月前
|
安全 前端开发 Android开发
拥抱国产化:转转APP的鸿蒙NEXT端开发尝鲜之旅
本文将要分享的是转转APP在开发全新鸿蒙NEXT端所遇到的一些问题,对比了鸿蒙开发和 Android、iOS 的不同,总结了这次开发过程中的一些经验等等。希望能带给你启发。
74 0
|
2月前
|
人工智能 JSON 小程序
【一步步开发AI运动APP】七、自定义姿态动作识别检测——之规则配置检测
本文介绍了如何通过【一步步开发AI运动APP】系列博文,利用自定义姿态识别检测技术开发高性能的AI运动应用。核心内容包括:1) 自定义姿态识别检测,满足人像入镜、动作开始/停止等需求;2) Pose-Calc引擎详解,支持角度匹配、逻辑运算等多种人体分析规则;3) 姿态检测规则编写与执行方法;4) 完整示例展示左右手平举姿态检测。通过这些技术,开发者可轻松实现定制化运动分析功能。
|
3月前
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
187 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
3月前
|
安全 API Swift
如何在苹果内购开发中获取App Store Connect API密钥-共享密钥理解内购安全-优雅草卓伊凡
如何在苹果内购开发中获取App Store Connect API密钥-共享密钥理解内购安全-优雅草卓伊凡
183 15
如何在苹果内购开发中获取App Store Connect API密钥-共享密钥理解内购安全-优雅草卓伊凡