Android7.0以上调用相机,有些手机会出现如下异常
android.os.FileUriExposedException: file:///storage/emulated/0/ exposed beyond app through ClipData.Item.getUri()
at android.os.StrictMode.onFileUriExposed(StrictMode.java:1975)
at android.net.Uri.checkFileUriExposed(Uri.java:2355)
at android.content.ClipData.prepareToLeaveProcess(ClipData.java:941)
at android.content.Intent.prepareToLeaveProcess(Intent.java:9944)
at android.content.Intent.prepareToLeaveProcess(Intent.java:9929)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1622)
调用相机代码如下
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0); startActivityForResult(intent, REQ_TAKE);
网上有人说在Application中添加如下
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
builder.detectFileUriExposure();
加完后发现不起作用。
7.0 调用系统相机拍照不再允许使用Uri方式,应该替换为FileProvider 解决办法如下: 在AndroidManifest里添加provider <!-- 解决 Android N 7.0 上 报错:android.os.FileUriExposedException --> <provider android:name="android.support.v4.content.FileProvider" android:authorities="这里写包名.fileProvider" android:exported="false" android:grantUriPermissions="true" tools:replace="android:authorities"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"/> </provider> 同时需要在res下的xml包下新建一个 file_paths.xml 文件,里面是这样的: <?xml version="1.0" encoding="utf-8"?> <paths> <!--<external-path path="Android/data/com.chemao.certification/" name="files_root" />--> <external-path name="img" path="myapp/img"/> </paths> file_path.xml里的标签用法如下
1.files-path
<files-path name="name" path="path" />
代表与Context.getFileDir()相同的文件路径
2.cache-path
<cache-path name="name" path="path" />
代表与getCacheDir()相同的文件路径
3.external-path
<external-path name="name" path="path" />
代表与Environment.getExternalStorageDirectory()相同的文件路径
4.external-files-path
<external-files-path name="name" path="path" />
代表与Context#getExternalFilesDir(String) 和Context.getExternalFilesDir(null)相同的文件路径
5.external-cache-path
<external-cache-path name="name" path="path" />
代表与Context.getExternalCacheDir()相同的文件路径
调用相机处代码
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion< Build.VERSION_CODES.N){
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(getUserDir(), )));
startActivityForResult(intent, TAKE_PHOTO);
} else{
File dir = new File(getDir() + "/img");
File file = new File(dir,”photo”);
String packageName = Application.getPackageName();
Uri imageUri = FileProvider.getUriForFile(activity, packageName + ".fileprovider", file);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, PHOTO);
}
注意这里的file一定要写res下path中的external-path