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

Android开发求助:如何在WebView中加载asset文件夹外的HTML文件

嘿,我完全懂你的困扰——刚入门Android开发,想让WebView加载外部驱动器里的HTML文件,结果搜出来的教程全是针对asset文件夹的,确实有点让人头大。别担心,我来一步步帮你搞定这个问题:

第一步:先搞定外部存储的访问权限

要读取外部存储里的文件,首先得申请权限,不同Android版本的权限要求不一样:

  • 静态权限配置:在AndroidManifest.xml里添加权限声明:
<!-- 适用于Android 12及以下 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Android 13+可以用更细化的媒体权限,按需添加 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
  • 动态权限申请:Android 6.0(API 23)及以上,还得在代码里主动请求权限,比如在Activity里:
private static final int REQUEST_STORAGE_PERMISSION = 100;

// 检查并请求权限
private void checkStoragePermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                REQUEST_STORAGE_PERMISSION);
    } else {
        // 权限已获取,开始加载文件
        loadHtmlFromExternalStorage();
    }
}

// 处理权限申请结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_STORAGE_PERMISSION) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            loadHtmlFromExternalStorage();
        } else {
            // 用户拒绝权限,提示处理
            Toast.makeText(this, "需要存储权限才能加载文件", Toast.LENGTH_SHORT).show();
        }
    }
}
第二步:加载外部HTML文件到WebView

这里分两种情况,对应不同的Android版本限制:

方法1:直接加载文件路径(Android 9及以下,或启用Legacy存储)

如果你的App目标版本是Android 9(API 28)及以下,或者在Android 10/11里启用了Legacy存储(在Manifest的application标签里加android:requestLegacyExternalStorage="true"),可以直接用file://协议加载:

private void loadHtmlFromExternalStorage() {
    WebView webView = findViewById(R.id.webview);
    // 开启JS支持(如果你的HTML里有JS的话)
    webView.getSettings().setJavaScriptEnabled(true);
    // 允许访问文件
    webView.getSettings().setAllowFileAccess(true);

    // 替换成你实际的文件路径,比如Downloads文件夹下的test.html
    File htmlFile = new File(Environment.getExternalStorageDirectory() + "/Downloads/test.html");
    if (htmlFile.exists()) {
        String filePath = htmlFile.getAbsolutePath();
        webView.loadUrl("file://" + filePath);
    } else {
        // 文件不存在时的提示
        webView.loadData("<h1>文件未找到</h1>", "text/html", "UTF-8");
    }
}

方法2:用FileProvider加载(Android 10+推荐)

从Android 10开始,系统启用了分区存储,直接用file://会被限制,所以推荐用FileProvider生成内容Uri来加载:

  1. 注册FileProvider:在AndroidManifest.xml的application标签里添加:
<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>
  1. 创建路径配置文件:在res/xml文件夹下新建file_paths.xml(没有xml文件夹就自己建一个):
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 允许访问外部存储根目录,你可以根据需求改路径,比如只允许Downloads -->
    <external-path name="external_files" path="." />
    <!-- 示例:只允许访问Downloads文件夹
    <external-public-path name="downloads" path="Downloads/" />
    -->
</paths>
  1. 代码里加载文件:
private void loadHtmlFromExternalStorage() {
    WebView webView = findViewById(R.id.webview);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setAllowFileAccess(true);
    webView.getSettings().setAllowContentAccess(true);

    // 示例:加载Downloads文件夹下的test.html
    File htmlFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "test.html");
    if (htmlFile.exists()) {
        // 生成内容Uri
        Uri fileUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", htmlFile);
        // 加载Uri
        webView.loadUrl(fileUri.toString());
    } else {
        webView.loadData("<h1>文件未找到</h1>", "text/html", "UTF-8");
    }
}
一些额外的小提示
  • 如果你的HTML里引用了本地的图片、CSS或JS文件,要确保这些文件的路径正确,并且WebView有权限访问它们(比如用同样的FileProvider方式,或者确保路径在你配置的FileProvider路径范围内)。
  • 要是遇到WebView加载空白的情况,可以给WebView设置一个WebChromeClient来查看错误日志:
webView.setWebChromeClient(new WebChromeClient() {
    @Override
    public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
        Log.d("WebViewLog", consoleMessage.message() + " -- From line "
                + consoleMessage.lineNumber() + " of "
                + consoleMessage.sourceId());
        return super.onConsoleMessage(consoleMessage);
    }
});
  • Android 13+记得用新的READ_MEDIA_*权限,旧的READ_EXTERNAL_STORAGE会被限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:14:15