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

Android中FileUriExposedException问题:如何打开内部存储图片文件夹

这个问题我太熟了!Android 7.0(API 24)及以上系统搞了个StrictMode限制,直接把file://格式的URI传给其他应用就会炸FileUriExposedException——说白了就是系统为了文件安全,不让跨应用直接访问file URI,得用FileProvider转成content://格式的URI才行。下面给你一步步搞定:

解决方案步骤

1. 在AndroidManifest.xml中注册FileProvider

在你的<application>标签内部添加provider配置,注意android:authorities要使用你的应用包名+自定义后缀(比如.fileprovider),确保唯一:

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

注意:如果你的项目用的是旧版支持库,就把androidx.core.content.FileProvider换成android.support.v4.content.FileProvider

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

在res/xml/目录下新建file_paths.xml文件(如果xml目录不存在就手动创建),用来指定FileProvider可以共享的目录。针对你的场景,我们需要共享外部存储中Pictures下的MyPhotos文件夹:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- external-path对应系统外部存储根目录 -->
    <external-path
        name="my_photos_alias"
        path="Pictures/MyPhotos/" />
</paths>

这里的path是你要共享的具体子目录,name是个别名,用来隐藏真实路径,避免安全风险。

3. 修改Java代码适配FileProvider

替换原来生成URI的逻辑,通过FileProvider获取content URI,同时做好版本兼容(低于API24的设备仍可使用file URI):

File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyPhotos");
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri folderUri;

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    // Android 7.0及以上,用FileProvider生成content URI
    folderUri = FileProvider.getUriForFile(this, "com.your.package.name.fileprovider", folder);
    // 给目标应用授予临时读权限
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
    // 低于7.0的设备,直接用file URI即可
    folderUri = Uri.parse("file://" + folder.getAbsolutePath());
}

// 调整Intent的Type,用"resource/folder"更适配多数文件管理器
intent.setDataAndType(folderUri, "resource/folder");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

try {
    startActivity(intent);
} catch (ActivityNotFoundException e) {
    // 处理没有应用能打开文件夹的情况,比如提示用户安装文件管理器
    Toast.makeText(this, "未找到可打开文件夹的应用", Toast.LENGTH_SHORT).show();
}

关键细节提醒

  • android:exported="false":必须设为false,FileProvider不能被导出,否则会有严重安全漏洞
  • FLAG_GRANT_READ_URI_PERMISSION:一定要加这个标志,不然目标应用会没有权限读取该目录下的文件
  • Intent Type适配:原来的*/*适配性较差,用"resource/folder"或"vnd.android.document/directory"能让更多文件管理器正确识别并打开文件夹

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:17:00