- 很多小伙伴都遇到过在调用相机时遇到过这样的坑,打开相机后直接闪退,然后返回个android.os.FileUriExposedException: file:///storage/emulated/0/xxx.jpg exposed beyond app through ClipData.Item.getUri();错误
- 今天我们就开分析一下这个问题的原因
原因
- 首先,Android 7.0版本以前 //加载路径 Uri uri = Uri.fromFile(new File(mFilePath)); file文件直接转成url
- Android 7.0版本以后Android不再允许在app中把file文件直接转成url
解决办法
- 首先我们在AndroidManifest文件中 application 标签中添加 provider 标签,代码如下:
//com.xxx.xxx App应用包名
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.xxx.xxx.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
- 然后我们在res文件夹中创建xml文件夹,在xml文件夹中新建file_paths文件,配置如下:
//com.xxx.xxx App应用包名
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="files_root" path="Android/data/com.xxx.xxx/" />
<external-path name="external_storage_root" path="."/>
<root-path
name="root_path"
path="." />
</paths>
paths内还可以声明很多种类型的标签,每一种标签都代表了一个路径,如下:
<files-path /> = getFilesDir()
<cache-path /> = getCacheDir()
<external-path /> = Environment.getExternalStorageDirectory()
<external-files-path /> = Context#getExternalFilesDir(String) 或 Context.getExternalFilesDir(null)
<external-cache-path /> = Context.getExternalCacheDir()
<external-media-path /> = Context.getExternalMediaDirs()
- 最后我们在项目中自定义的Application的onCrete() 方法中添加 如下配置:
@Override
public void onCreate() {
super.onCreate();
......
//允许7.0手机打开手机下的文件路径 否则将无法使用拍照功能
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StrictMode.VmPolicy.Builder b = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(b.build());
}
}
在使用相机时不要忘记了动态申请相机权限,好了,今天的分享就到此结束了~~~