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

Android WebView如何将大型二进制ZIP文件传递给Javascript处理

核心问题原因

你fetch失败的根本原因是WebView默认将裸本地路径视为当前站点的相对路径,所以会请求你的Web服务端的对应路径,返回404错误。


问题1:验证文件创建成功并支持JS访问

  • 原生侧文件校验:写入完成后调用file2.exists()判断文件是否存在,调用file2.length()获取文件大小,和原ZIP大小对比,确认文件写入无异常。
  • WebView权限配置:初始化WebView时开启本地文件访问权限:
// 允许WebView访问本地文件
webView.getSettings().setAllowFileAccess(true);
// 若你的Web应用是远程http/https页面,需开启跨域访问本地文件权限
webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
  • 路径格式修正:传给JS的文件路径需要加file://前缀,即完整路径为file:///storage/emulated/0/Android/data/com.example/files/Download/file2.zip,JS fetch该路径即可正常获取文件内容。

问题2:无需复制文件直接让JS访问原始文件

首先明确:安卓10及以上系统已经限制应用直接获取外部存储文件的真实路径,你找真实路径的思路无法适配全版本系统,不建议继续尝试。

最优解决方案是通过WebView请求拦截实现,步骤如下:

  1. 原生侧拿到onActivityResult返回的content URI(即你日志输出的content://com.android.providers.downloads.documents/document/msf%3A12858),直接传给JS使用。
  2. 重写WebViewClient的shouldInterceptRequest方法,拦截content协议的请求,直接返回文件输入流给WebView:
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
    Uri requestUri = request.getUrl();
    // 拦截所有content协议的请求
    if ("content".equals(requestUri.getScheme())) {
        try {
            // 通过ContentResolver打开文件输入流
            InputStream inputStream = getContentResolver().openInputStream(requestUri);
            // 获取文件MIME类型
            String mimeType = getContentResolver().getType(requestUri);
            return new WebResourceResponse(mimeType, "UTF-8", inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return super.shouldInterceptRequest(view, request);
}

该方案完全不需要复制文件,直接复用系统返回的content URI,支持任意大小的文件,也不会有跨域问题,适配所有安卓版本。


内容的提问来源于stack exchange,提问作者Avner Moshkovitz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 04:48:02