Android 7.0拍照、选择照片相关错误
原创
©著作权归作者所有:来自51CTO博客作者是丹凤呀的原创作品,请联系作者获取转载授权,否则将追究法律责任
1、
s.FileUriExposedException: file:///storage/emulated/0/DCIM/IMG_4146227344282226873.jpg exposed beyond app through ClipData.Item.getUri()
(1)Android manifest中添加一下代码,最好使用${applicationId}
<!--sdk 24 以上 拍照需要特殊处理-->
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
(2)在values目录下创建xml文件夹,再创建provider_paths.xml文件
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!--"."表示所有路径-->
<external-path name="com.flyfish.healthmanage_prac.fileprovider" path="."/>
</paths>
(3)调用相机时,做特殊处理
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.putExtra(MediaStore.EXTRA_OUTPUT,
FileProvider.getUriForFile(this, AppConfig.getApplicationContext().getPackageName() + ".fileprovider", file));
} else {
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
}
(4)如果还涉及到剪裁图片,也需要做处理, intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
/*
* 剪切图片
*/
private void cropImg(Uri uri) {
// 裁剪图片意图
Intent intent = new Intent("com.android.camera.action.CROP");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
// 裁剪框的比例,1:1
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// 裁剪后输出图片的尺寸大小
intent.putExtra("outputX", 250);
intent.putExtra("outputY", 250);
mTempFile = new File(getExternalCacheDir(), "temp.png");
//必须将结果存成图片,因为"return-data", true,参数对返回图片大小有限制,
//图片过大时返回的Intent =null,小米手机就会存在这个问题
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTempFile));
intent.putExtra("outputFormat", "JPEG");// 图片格式
intent.putExtra("noFaceDetection", true);// 取消人脸识别
intent.putExtra("return-data", true);
// 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CUT
startActivityForResult(intent, PHOTO_REQUEST_CUT);
}
接收剪裁结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PHOTO_REQUEST_CUT) {
// 从剪切图片返回的数据
if (data != null) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(Uri.fromFile(mTempFile)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//保存到SharedPreferences
comPressBitmap(bitmap);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
//保存图片到SharedPreferences
private void comPressBitmap(Bitmap bitmap) {
// Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.ic);
//第一步:将Bitmap压缩至字节数组输出流ByteArrayOutputStream
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 80, byteArrayOutputStream);
//上传头像
upLoadImg(bitmap);
}
2、
.IllegalArgumentException: Failed to find configured root that contains /storage/6130-6330/DCIM/P71024-164048.jpg
需要在上面的provider_paths.xml中添加root-path这一项。
想要了解更多推荐:https://www.jianshu.com/p/121bbb07cb07
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!--"."表示所有路径-->
<external-path name="com.flyfish.healthmanage_prac.fileprovider" path="."/>
<root-path
name="root_path"
path="." />
</paths>
3、
如果你跟我一样使用了MultiImageSelector,在MultiImageSelector设置可以拍照时也会报一个错误,
s.FileUriExposedException: file:///storage/emulated/0/DCIM/IMG_4146227344282226873.jpg exposed beyond app through ClipData.Item.getUri()
(好像是上面这个错误,有点记不清了),可以通过在baseApplication中设置下面几行代码来解决
// android 7.0系统解决拍照的问题
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
builder.detectFileUriExposure();
}