使用kotlin Jetpack Compose框架开发安卓app, webview中h5如何访问手机存储上传文件

简介: 在Kotlin和Jetpack Compose中,集成WebView以支持HTML5页面访问手机存储及上传音频文件涉及关键步骤:1) 添加`READ_EXTERNAL_STORAGE`和`WRITE_EXTERNAL_STORAGE`权限,考虑Android 11的分区存储;2) 配置WebView允许JavaScript和文件访问,启用`javaScriptEnabled`、`allowFileAccess`等设置;3) HTML5页面使用`<input type="file">`让用户选择文件,利用File API;

在Kotlin中开发Android应用时,如果你想要在WebView中处理HTML5的<input type="file">标签以触发文件选择器,你可以结合使用registerForActivityResult(也称为rememberLauncherForActivityResult,但在Fragment中更常用的是前者)和WebChromeClient。以下是一个在Activity中实现的示例代码,展示了如何设置WebView并处理文件选择。


在你的Activity中,设置WebView,并注册一个用于处理文件选择的ActivityResultLauncher,同时设置WebChromeClient以监听文件选择器的请求:

import android.content.Intent  
import android.net.Uri  
import android.os.Bundle  
import android.webkit.ValueCallback  
import android.webkit.WebChromeClient  
import android.webkit.WebView  
import android.webkit.WebViewClient  
import androidx.activity.result.ActivityResultLauncher  
import androidx.activity.result.contract.ActivityResultContracts  
import androidx.appcompat.app.AppCompatActivity  
  
class MainActivity : AppCompatActivity() {  
  
    private lateinit var webView: WebView  
    private lateinit var fileChooserLauncher: ActivityResultLauncher<Intent>  
  
    override fun onCreate(savedInstanceState: Bundle?) {  
        super.onCreate(savedInstanceState)  
        setContentView(R.layout.activity_main)  
  
        webView = findViewById(R.id.webview)  
  
        // 设置WebViewClient处理页面加载  
        webView.webViewClient = WebViewClient()  
  
        // 设置WebChromeClient处理文件选择等  
        webView.webChromeClient = object : WebChromeClient() {  
            override fun onShowFileChooser(  
                webView: WebView?,  
                filePathCallback: ValueCallback<Array<Uri>>?,  
                fileChooserParams: FileChooserParams?  
            ): Boolean {  
                // 创建Intent来启动文件选择器  
                val intent = Intent(Intent.ACTION_GET_CONTENT)  
                intent.type = "*/*" // 设置MIME类型,这里表示所有类型  
                intent.addCategory(Intent.CATEGORY_OPENABLE)  
  
                // 使用ActivityResultLauncher启动Intent  
                fileChooserLauncher.launch(intent)  
  
                // 必须返回true,表示文件选择器将被处理  
                return true  
            }  
        }  
  
        // 加载网页  
        webView.loadUrl("https://your-website.com/page-with-file-input.html")  
  
        // 注册ActivityResultLauncher以处理文件选择结果  
        fileChooserLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->  
            if (result.resultCode == RESULT_OK) {  
                // 处理选择的文件,这里假设filePathCallback是全局可访问的  
                // 注意:在实际应用中,filePathCallback可能不是全局的,你需要通过其他方式传递它  
                // 例如,你可以将WebView的引用和filePathCallback一起传递给一个自定义的类,该类将处理文件选择  
                // 这里只是示例,所以省略了这部分逻辑  
  
                // 假设你有一个全局的filePathCallback变量  
                // filePathCallback?.onReceiveValue(arrayOf(result.data?.data))  
            }  
        }  
    }  
  
    // 注意:上面的filePathCallback处理是简化的,实际中你可能需要不同的逻辑  
    // 因为在WebChromeClient的onShowFileChooser方法中,filePathCallback是局部的  
    // 你需要找到一种方法来在文件选择结果返回时调用它  
  
    // 一种可能的解决方案是使用弱引用或全局变量(但请注意内存泄漏的风险)  
    // 或者,你可以将WebView的引用和filePathCallback一起封装在一个自定义的类中  
}

注意:上面的代码示例中,filePathCallback的处理是简化的,因为在实际情况下,filePathCallback是在onShowFileChooser的局部作用域中定义的,并且不是全局可访问的。因此,你需要找到一种方法来在文件选择结果返回时调用它。

一种常见的做法是将WebView的引用和filePathCallback一起封装在一个自定义的类中,该类将负责处理文件选择请求和结果。这样,你就可以在文件选择结果返回时,通过该类的实例来调用filePathCallback。

相关文章
|
12月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1977 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
12月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1261 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
12月前
|
移动开发 Rust JavaScript
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1332 4
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
开发工具 Android开发
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
1079 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
|
12月前
|
移动开发 Android开发
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
575 0
|
Java 开发工具 Maven
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
1543 6
|
安全 数据库 Android开发
在Android开发中实现两个Intent跳转及数据交换的方法
总结上述内容,在Android开发中,Intent不仅是活动跳转的桥梁,也是两个活动之间进行数据交换的媒介。运用Intent传递数据时需注意数据类型、传输大小限制以及安全性问题的处理,以确保应用的健壯性和安全性。
806 11
|
安全 Java Android开发
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
605 0
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
|
移动开发 Java 编译器
Kotlin与Jetpack Compose:Android开发生态的演进与架构思考
本文从资深Android工程师视角深入分析Kotlin与Jetpack Compose在Android系统中的技术定位。Kotlin通过空安全、协程等特性解决了Java在移动开发中的痛点,成为Android官方首选语言。Jetpack Compose则引入声明式UI范式,通过重组机制实现高效UI更新。两者结合不仅提升开发效率,更为跨平台战略和现代架构模式提供技术基础,代表了Android开发生态的根本性演进。
675 0
|
传感器 安全 生物认证
iOS传感器开发——为APP添加手机密码、指纹进行安全验证
iOS传感器开发——为APP添加手机密码、指纹进行安全验证
450 0
iOS传感器开发——为APP添加手机密码、指纹进行安全验证