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

创建独立文件夹保存无损拍摄图片遇FileUriExposedException异常求修正

嘿,这个问题我太熟了!你碰到的是 Android 7.0(API 24)及以上版本的安全限制——系统不再允许直接通过 file:// URI 把文件暴露给其他应用(比如相机应用),这就是 FileUriExposedException 的由来。

错误原因分析

你直接用 Environment.getExternalStorageDirectory() 创建文件后生成了 file:// 格式的 URI,在高版本系统中,这种跨应用的文件共享属于不安全操作,系统会直接抛出异常阻止。正确的做法是用 FileProvider 生成 content:// 格式的 URI,这是 Android 官方要求的安全文件共享机制。

修正步骤

我一步步帮你改代码:

1. 在 AndroidManifest.xml 中注册 FileProvider

打开你的清单文件,在 <application> 标签内添加以下配置:

<application ...>
    <!-- 注册FileProvider -->
    <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>
  • 如果你用的是旧版 support 库,把 androidx.core.content.FileProvider 换成 android.support.v4.content.FileProvider
  • authorities 用 ${applicationId}.fileprovider 可以避免和其他应用冲突,也可以自定义后缀,但要保持唯一

2. 创建 FileProvider 路径配置文件

在 res 目录下新建 xml 文件夹,然后创建 file_paths.xml 文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 配置要共享的外部存储目录:myFolder -->
    <external-path name="my_images" path="myFolder/" />
</paths>

这个文件告诉 FileProvider,我们要共享外部存储中 myFolder 目录下的所有文件。

3. 修改代码生成安全的 URI

保留你创建文件夹的代码,然后替换生成 URI 的逻辑:

String folder_main = "myFolder";
File f = new File(Environment.getExternalStorageDirectory(), folder_main);
if (!f.exists()) {
    f.mkdirs();
}

// 生成文件名(补全你的时间戳逻辑)
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
File photoFile = new File(f, "photo_" + timeStamp + ".png");

Uri photoUri;
Context context = getApplicationContext(); // 或者用当前Activity的上下文
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    // Android 7.0及以上,用FileProvider生成content:// URI
    photoUri = FileProvider.getUriForFile(
        context,
        context.getPackageName() + ".fileprovider", // 和Manifest里的authorities一致
        photoFile
    );
    // 给目标应用(比如相机)授予临时读取权限
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
    // Android 7.0以下,直接用file:// URI
    photoUri = Uri.fromFile(photoFile);
}

// 把URI传给相机Intent(示例)
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(takePictureIntent, 1001); // 替换成你的请求码

额外注意事项

  • 确保你的应用已经申请了 WRITE_EXTERNAL_STORAGE 权限(Android 6.0及以上需要动态申请)
  • Android 10及以上可以考虑用 Scoped Storage,但如果你是和相机共享文件,上述 FileProvider 的方案依然适用
  • exported="false" 必须设置为 false,这是 FileProvider 的安全要求,禁止外部应用直接访问

这样修改后,就能解决 FileUriExposedException 的问题,同时也能保证图片画质不损失~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:56:45