已设置WebView相关标志仍遇net::ERR_ACCESS_DENIED问题求助
我尝试加载应用启动时生成并保存至以下路径的HTML文件:
/data/data/com.me.myapp/files/autogen.html
使用的工具类代码如下:
public class FileUtils { public static void saveToInternalFile(Context ctx, String fname, String html) { try (var fos = Files.newOutputStream( Paths.get(ctx.getFilesDir().getAbsolutePath(), fname), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) { fos.write(html.getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { e.printStackTrace(); } } public static String constructInternalFileUrl(Context ctx, String filename) { return "file://" + new File(ctx.getFilesDir(), filename).getAbsolutePath(); } }
通过Device Explorer确认文件存在,且可在Edge、Firefox和Chrome中正常读取。但在同一应用的同一运行会话中,将以下URL加载至WebView时:
file:///data/user/0/com.me.myapp/files/autogen.html
出现如下错误:
The webpage at file:///data/user/0/com.me.myapp/files/autogen.html could not be loaded because: net::ERR_ACCESS_DENIED
尽管我已设置相关WebView标志:
WebSettings webSettings = getSettings(); webSettings.setDomStorageEnabled(true); webSettings.setAllowContentAccess(true); webSettings.setAllowFileAccessFromFileURLs(true); webSettings.setAllowUniversalAccessFromFileURLs(true);
请问我可能遗漏了什么?
注:此问题并非相关Stack Overflow帖子的重复,我已实现这些帖子中建议的所有方案,但未取得成效。
可能的解决方向
1. 改用WebAssetLoader加载(Android 11+推荐)
从Android 11开始,直接使用file://协议访问内部存储文件会受到沙箱限制,WebView的独立进程可能无法直接读取。推荐使用WebAssetLoader来安全加载内部文件:
// 初始化WebAssetLoader WebAssetLoader assetLoader = new WebAssetLoader.Builder() .addPathHandler("/files/", new InternalStoragePathHandler(context)) .build(); // 给WebView设置自定义WebViewClient webView.setWebViewClient(new WebViewClient() { @Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { return assetLoader.shouldInterceptRequest(request.getUrl()); } }); // 自定义内部存储路径处理器 private static class InternalStoragePathHandler implements WebAssetLoader.PathHandler { private final Context context; InternalStoragePathHandler(Context context) { this.context = context; } @Override public WebResourceResponse handle(String path) throws IOException { // 去掉前缀,获取文件名 String fileName = path.replace("/files/", ""); File file = new File(context.getFilesDir(), fileName); return new WebResourceResponse( "text/html", "UTF-8", new FileInputStream(file) ); } }
之后加载的URL需要改为:https://appassets.androidplatform.net/files/autogen.html
2. 检查文件权限
确保生成的HTML文件允许WebView进程读取。可以在保存文件后添加权限设置:
File file = new File(ctx.getFilesDir(), fname); // 设置文件为全局可读(注意:存在安全风险,仅临时排查使用) file.setReadable(true, false);
3. 确认WebSettings配置时机
必须在WebView加载URL之前完成所有WebSettings的配置,避免配置未生效。
4. 多进程WebView的特殊处理
如果WebView运行在独立进程(AndroidManifest中给WebView所在Activity设置了android:process),内部存储文件默认仅主进程可访问。此时可以:
- 使用ContentProvider共享文件给WebView进程
- 避免让WebView运行在独立进程(如果业务允许)
内容的提问来源于stack exchange,提问作者sfinja

