Android 11 带文件路径的系统相机Intent失效崩溃问题咨询
Android 11 系统调起相机崩溃的针对性修复方案
核心崩溃点1:FileProvider路径映射与实际存图路径不匹配
- 你当前存图逻辑使用的是
getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES),该方法返回的实际路径为/storage/emulated/0/Android/data/<你的应用包名>/files/Pictures,属于应用沙盒专属的外部存储目录 - 现有
file_paths.xml的配置完全无法覆盖上述路径:<external-path name="my_images" path="AppName/Temp/" />:对应公共外部存储根目录下的AppName/Temp子文件夹,和实际存图路径无交集<external-path name="external_files" path="." />:对应公共外部存储根目录(即Environment.getExternalStorageDirectory()的返回值),同样无法匹配沙盒目录的路径前缀
- 按照FileProvider的严格校验规则,只有传入的文件路径能被xml声明的规则作为前缀匹配时,才能正常生成可共享的Uri,否则会直接抛出
IllegalArgumentException: Failed to find configured root that contains /xxx。低版本系统对该规则的校验存在容错,Android 11上校验逻辑完全收紧,这是最高概率的崩溃诱因 - 修复配置:调整
file_paths.xml,新增对应用专属外部目录的映射:<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 匹配getExternalFilesDir(DIRECTORY_PICTURES)对应的沙盒目录 --> <external-files-path name="app_pictures" path="Pictures" /> </paths>
核心崩溃点2:未显式授予相机应用Uri访问权限
- 虽然FileProvider节点配置了
android:grantUriPermissions="true",但Android 11对Uri权限的管控改为与Intent强绑定,若不显式为Intent添加读写权限标记,相机应用拿到Uri后会因无访问权限直接抛出SecurityException - 修复代码:在构造拍照Intent时补上权限授予flag:
if (photoFile != null) { Uri photoURI = FileProvider.getUriForFile( context.getApplicationContext(), getActivity().getPackageName()+".fileprovider", photoFile ); pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); // 新增:显式授予相机对该Uri的读写权限 pictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); startActivityForResult(pictureIntent, 1); }
适配Android 11包可见性规则
- Android 11引入的包可见性机制默认不允许应用查询其他应用的组件信息,你代码中的
resolveActivity()判断会因为查询不到相机应用直接返回null,部分ROM会因此触发异常 - 修复方式:在AndroidManifest.xml中添加对应的查询声明,允许应用识别可响应当前拍照Intent的应用:
<queries> <intent> <action android:name="android.media.action.IMAGE_CAPTURE" /> </intent> </queries> - 额外优化:你当前的存图逻辑使用的是应用专属沙盒目录,该目录不需要任何外部存储权限即可读写,Manifest中声明的
READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE、MANAGE_EXTERNAL_STORAGE属于冗余配置,在Android 11上反而可能因为特殊权限申请流程缺失触发异常,建议直接移除。
快速排查技巧
遇到崩溃时优先查看Logcat中的异常堆栈,可快速定位问题:
- 若报错包含
Failed to find configured root that contains:为FileProvider路径映射配置错误 - 若报错包含
Permission Denial: reading xxx uri:为Uri权限授予缺失 - 若报错为resolveActivity返回null、无相机组件响应:为包可见性queries配置缺失
内容的提问来源于stack exchange,提问作者jahangir alam
相关产品推荐
相关产品推荐

