Android 11设备CAT S42调用MediaStore拍照生成0字节文件问题
问题原因
Android 11(API 30)及以上版本对跨应用文件访问有严格限制:
- 直接用
Uri.fromFile()传递file://格式的Uri给相机应用,会触发FileUriExposedException,且相机应用没有权限访问你的App私有目录(getFilesDir()属于App私有空间),导致相机无法写入照片,最终生成0字节文件。旧机型系统版本低,没有这些权限限制,所以代码能正常运行。
解决方案:改用FileProvider生成内容Uri
1. 清单文件注册FileProvider
在<application>标签内添加以下配置,替换your.package.name为你的App实际包名:
<provider android:name="androidx.core.content.FileProvider" android:authorities="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>
2. 创建文件路径配置文件
在res/xml目录下新建file_paths.xml文件(若没有xml目录则手动创建),内容如下:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 配置共享App私有目录下的files文件夹 --> <files-path name="my_files" path="." /> </paths>
3. 修改相机调用代码
更新startCamera()方法,用FileProvider生成合法的内容Uri,并授予相机临时读写权限:
private void startCamera() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (intent.resolveActivity(getPackageManager()) != null) { File mNewPhoto = new File(getFilesDir(), "data-input-image.jpg"); // 通过FileProvider生成内容Uri Uri photoUri = FileProvider.getUriForFile(this, "your.package.name.fileprovider", mNewPhoto); // 授予相机临时读写权限 intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); startActivityForResult(intent, 1); } }
额外说明
- 若使用AndroidX库,确保依赖中包含
androidx.core:core-ktx或androidx.core:core(版本建议1.3.0及以上)。 - 此方案无需额外申请存储权限,因为访问的是App私有目录,且通过FileProvider共享符合Android 11的权限规则。
内容的提问来源于stack exchange,提问作者user3352488
相关产品推荐
相关产品推荐

