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

如何调用grantUriPermissions为ACTION_VIEW的引用文件授予Uri权限

解决方案

方案1:通过ClipData批量附加目录内所有资源URI(合规推荐,无需解析HTML)

该方案利用Android系统原生特性:Intent附加的ClipData内包含的所有URI,都会自动被授予Intent上设置的读写权限,无需手动逐个授权,也不需要解析HTML内容判断引用的资源。
实现步骤:

  1. 当检测到要打开的是.html类型文件时,获取该HTML文件所在的父目录
  2. 遍历父目录下的所有文件(可按需调整遍历的子目录深度),生成对应的FileProvider URI
  3. 把所有URI构造为ClipData附加到Intent上,系统会自动完成批量授权

代码示例:

// 原有Intent构造逻辑不变
Intent deflt = new Intent();
deflt.setAction(android.content.Intent.ACTION_VIEW);
deflt.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
deflt.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
deflt.setDataAndType(uri, mime);

// 仅针对HTML文件增加批量授权逻辑
if ("text/html".equals(mime)) {
    File htmlFile = new File(本地HTML文件的绝对路径);
    File parentDir = htmlFile.getParentFile();
    List<Uri> allResUris = new ArrayList<>();
    // 遍历目录下所有文件生成URI
    traverseResDir(parentDir, allResUris);
    // 构造ClipData附加到Intent
    if (!allResUris.isEmpty()) {
        ClipData clipData = ClipData.newRawUri(null, allResUris.get(0));
        for (int i = 1; i < allResUris.size(); i++) {
            clipData.addItem(new ClipData.Item(allResUris.get(i)));
        }
        deflt.setClipData(clipData);
    }
}

startActivity(deflt);

对应的目录遍历方法:

private void traverseResDir(File dir, List<Uri> uriList) {
    File[] files = dir.listFiles();
    if (files == null) return;
    for (File file : files) {
        if (file.isDirectory()) {
            traverseResDir(file, uriList);
        } else {
            // 可在此处增加后缀过滤,仅添加图片、CSS、JS等资源文件减少开销
            Uri resUri = FileProvider.getUriForFile(this, "你的FileProvider授权标识", file);
            uriList.add(resUri);
        }
    }
}

该方案完全符合Android权限规范,兼容性覆盖Android 4.4及以上系统,只要HTML引用的资源都在同级目录下就可以正常加载。

方案2:临时禁用FileUri暴露检查(最简方案,适合快速实现)

如果不需要严格遵循Android官方规范,可直接使用file://格式URI传递,跳过FileProvider的权限限制,浏览器可以直接访问同目录下所有本地文件,不需要额外授权逻辑。
仅需要在Application或者启动页Activity的onCreate方法中添加一行代码禁用暴露检查:

StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().build());

之后构造Intent的时候直接传递原生文件URI即可:

deflt.setDataAndType(Uri.fromFile(htmlFile), "text/html");

注意:该方案不符合Android 7.0之后的官方开发规范,仅适合个人开发或内部使用的应用,正式上线应用不推荐使用。

内容的提问来源于stack exchange,提问作者Luis A. Florit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 05:39:05