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

Android相机FileUriExposedException求助:配置Provider仍报错

解决Android FileUriExposedException问题(使用Content URI替代File URI)

Hey,我来帮你搞定这个烦人的异常!你遇到的FileUriExposedException是Android 7.0(API 24)引入的安全机制导致的——直接用Uri.fromFile()生成的File URI会被系统判定为不安全,不允许跨应用共享,所以必须换成Content URI来实现文件共享。虽然你已经配置了Provider,但大概率是配置细节或者代码使用方式不对,下面给你完整的分步解决方案:

1. 确认Manifest中的FileProvider配置是否正确

首先,确保你在AndroidManifest.xml的<application>标签内正确配置了FileProvider,注意authorities字段要和后续代码保持完全一致,并且exported必须设为false,grantUriPermissions设为true:

<application ...>
    <!-- 其他组件配置 -->
    
    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="br.com.viniciusdeep.agenda.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>
</application>

注意:如果你用的是旧版支持库而非AndroidX,把androidx.core.content.FileProvider换成android.support.v4.content.FileProvider即可。

2. 创建文件路径配置文件

在res/xml目录下新建file_paths.xml文件(如果没有xml目录,直接右键res文件夹→New→Directory创建),配置你要共享的文件路径。因为你用的是getExternalFilesDir(null)(应用外部私有目录),所以用external-files-path标签:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- name是自定义标识,path="."表示共享该目录下所有文件 -->
    <external-files-path
        name="captured_images"
        path="." />
</paths>

3. 修改代码生成Content URI并授予权限

把原来生成File URI的代码替换成FileProvider生成Content URI的逻辑,同时要给拍照Intent添加临时访问权限,让相机应用能读取这个文件:

// 生成图片文件路径(和你原来的逻辑一致)
String caminhoFoto = getExternalFilesDir(null) + "/" + System.currentTimeMillis() + ".jpg";
File arquivoFoto = new File(caminhoFoto);

// 生成Content URI,注意第二个参数要和Manifest中的authorities完全匹配
Uri contentUri = FileProvider.getUriForFile(
        this,
        "br.com.viniciusdeep.agenda.fileprovider",
        arquivoFoto
);

// 创建拍照Intent
Intent intentImage = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 授予相机应用临时读取权限
intentImage.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// 替换原来的File URI为Content URI
intentImage.putExtra(MediaStore.EXTRA_OUTPUT, contentUri);

// 启动拍照Intent(记得定义自己的请求码,比如REQUEST_CODE_TAKE_PHOTO = 100)
startActivityForResult(intentImage, REQUEST_CODE_TAKE_PHOTO);

4. 拍照后的结果处理(可选但实用)

因为你已经指定了EXTRA_OUTPUT,相机应用会直接把照片保存到你创建的arquivoFoto文件中,所以在onActivityResult(或者AndroidX的registerForActivityResult)里,直接通过这个文件对象就能访问拍摄的照片,不需要从返回的Intent中取数据。

额外注意事项

  • 如果你需要兼容Android 6.0(API 23)及以下,确保已经动态申请了相机权限;Android 10(API 29)及以上,因为getExternalFilesDir属于应用私有目录,不需要申请存储权限。
  • 测试时尽量用API 24及以上的设备/模拟器,确保能复现和验证修复效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:11:44