解决Android7.0选择相机拍照异常退出
程序员文章站
2022-04-15 22:12:22
...
今天早上发现我们的app选择拍照功能突然异常退出,查看报错日志显示如下(这几天正在升级我们app的api,本来以为是Android8.0的错误呢):
Caused by: android.os.FileUriExposedException: file:///storage/emulated/0/Timers4Me/1531703834841.jpg exposed beyond app through ClipData.Item.getUri()
引起这个异常的原因:
从Android 7.0开始,不再允许在app中把file:// Uri暴露给其他app,否则应用会抛出FileUriExposedException。原因在于,Google认为使用file:// Uri存在一定的风险。比如,文件是私有的,其他app无法访问该文件,或者其他app没有申请READ_EXTERNAL_STORAGE运行时权限。
解决方案有两种:
- 使用FileProvider生成content:// Uri来替代file:// Uri
- 开启严格模式并关闭对文件的检测
一、比较推崇的是第一种解决方案:
1)在AndroidManifest.xml里application下添加如下代码段:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.luckyxmobile.timers4meplus.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
简单的只需将android:authorities改成“你的包名 +.fileprovider”,一定要注意细节
2)在xml目录下添加file_paths.xml(名字可以随便起,引用对就行了)
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external" path="." />
</paths>
3)下面是真正的获取Uri的代码段,tempFile(File)是要获取的文件,fileUri(Uri)是要获取文件的Uri
//Android7.0以上使用 content://来替代file://Uri。
if (Build.VERSION.SDK_INT >= 24) {
fileUri =FileProvider.getUriForFile(mContext,"com.luckyxmobile.timers4meplus.fileprovider",tempFile);
}else{
fileUri = Uri.fromFile(tempFile);
}
二、比较简单的是第二个解决方案:在aplication类的onCreate()里面添加一下几句就可以了:
// android 7.0系统解决拍照的问题
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
builder.detectFileUriExposure();
第二种解决方案只适合于开发模式的时候哦!!!