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
相关产品推荐
相关产品推荐

