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

Android WebView中img标签如何显示SD卡图片?问题求助

解决WebView中无法显示SD卡图片URI的问题

以下是几个可行的解决方案,按优先级排序:

方案1:使用FileProvider生成content://格式的URI(推荐)

从Android 7.0开始,直接使用file:// URI会触发FileUriExposedException,且WebView对file://资源的访问有严格权限限制,改用content://格式的URI可以彻底解决这类问题。

步骤1:配置FileProvider

在AndroidManifest.xml中注册FileProvider:

<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>
    ...
</application>

步骤2:创建文件路径配置

在res/xml目录下新建file_paths.xml,定义允许共享的文件路径(示例为SD卡DCIM目录,可根据实际存储路径调整):

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="camera_photos" path="DCIM/" />
    <!-- 若需共享整个外部存储,可替换为:
    <external-path name="external_storage" path="." />
    -->
</paths>

步骤3:生成content URI并传递给JS

修改拍照逻辑,用FileProvider生成合规的URI:

// 先创建目标图片文件
File imageFile = new File(mActivity.getExternalFilesDir(Environment.DIRECTORY_DCIM), "photo_" + System.currentTimeMillis() + ".jpg");
// 生成content://格式的URI
imgUri = FileProvider.getUriForFile(mActivity, mActivity.getPackageName() + ".fileprovider", imageFile);

// 保留原有拍照回调逻辑,传递的URI已为合规格式
mCaramerLauncher = mActivity.registerForActivityResult(new ActivityResultContracts.TakePicture(), new ActivityResultCallback<Boolean>() {
    @Override
    public void onActivityResult(Boolean result) {
        JsonObject rsJson = new JsonObject();
        if(result){
            rsJson.addProperty("uri", imgUri.toString()); // 现在是content://开头的URI
            rsJson.addProperty("code", 0);
        }else{
            rsJson.addProperty("data", "");
            rsJson.addProperty("code", 1);
        }
        jsCallParam.mCallback.callback(baseTMFWeb, rsJson.toString());
    }
});

方案2:将图片转为Base64字符串传递给JS

如果不想配置FileProvider,可以直接把图片转为Base64字符串,让HTML通过data URI加载:

修改拍照回调代码:

mCaramerLauncher = mActivity.registerForActivityResult(new ActivityResultContracts.TakePicture(), new ActivityResultCallback<Boolean>() {
    @Override
    public void onActivityResult(Boolean result) {
        JsonObject rsJson = new JsonObject();
        if(result){
            try {
                // 读取图片文件为字节数组
                File imageFile = new File(imgUri.getPath());
                FileInputStream fis = new FileInputStream(imageFile);
                byte[] bytes = new byte[(int) imageFile.length()];
                fis.read(bytes);
                fis.close();
                // 转为Base64格式的图片数据
                String base64Img = Base64.encodeToString(bytes, Base64.DEFAULT);
                rsJson.addProperty("imgData", "data:image/jpeg;base64," + base64Img);
                rsJson.addProperty("code", 0);
            } catch (IOException e) {
                e.printStackTrace();
                rsJson.addProperty("code", 1);
                rsJson.addProperty("msg", "图片读取失败");
            }
        }else{
            rsJson.addProperty("data", "");
            rsJson.addProperty("code", 1);
        }
        jsCallParam.mCallback.callback(baseTMFWeb, rsJson.toString());
    }
});

在HTML中直接使用该Base64字符串作为img的src:

<img src="data:image/jpeg;base64,xxx" />

方案3:Android 10及以下临时兼容(不推荐)

若应用仅兼容Android 10(API 29)及以下版本,可尝试添加以下WebSettings配置,但该方式在Android 11+已被废弃且存在安全风险:

webSettings.setAllowFileAccessFromFileURLs(true);
webSettings.setAllowUniversalAccessFromFileURLs(true);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:01:22