本文章解决思路:使用FileProvider
使用FileProvider的大致步骤如下:
第一步:在manifest清单文件中注册provider
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.techfly.global_village.fileProvider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
其中com.xxx.xxx为包名
exported:要求必须为false,为true则会报安全异常。
grantUriPermissions:true,表示授予 URI 临时访问权限。
第二步:指定共享的目录
为了指定共享的目录我们需要在资源(res)目录下创建一个xml目录,然后创建一个名为“file_paths”(名字可以随便起,只要和在manifest注册的provider所引用的resource保持一致即可)的资源文件,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
第三步:使用FileProvider
//拍照
Intent cIntent = new Intent(Intent.ACTION_PICK, null);
cIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri imageUri;
File file = new File(Environment.
getExternalStorageDirectory(), "/Download/upload.png");
if (!file.getParentFile().exists()) file.getParentFile().mkdirs();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
imageUri = FileProvider.getUriForFile(context, "com.techfly.global_village.fileProvider", file);//通过FileProvider创建一个content类型的Uri
////添加这一句表示对目标应用临时授权该Uri所代表的文件
cIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
imageUri = Uri.fromFile(file);
}
cIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(cIntent, CAMERA_REQUEST_CODE);
添加了intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);来对目标应用临时授权该Uri所代表的文件
//图片选择的方法不做改动
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
// startActivityForResult(intent, GALLERY_REQUEST_CODE);
startActivityForResult(intent, GALLERY_REQUEST_CODE);
//图片裁剪
//裁剪的参数统一为Uri
private void startImageZoom(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
// intent.setDataAndType(uri, "image/");
//7.0适配 FileProvider
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
String url = getPath(PersonDataActivity.this, uri);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri imageUri = FileProvider.getUriForFile(this, "com.techfly.global_village.fileProvider",
new File(url));//通过FileProvider创建一个content类型的Uri
intent.setDataAndType(imageUri, "image/");
} else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
Log.i("TTSS", "startImageZoom..1");
String url = getPath(PersonDataActivity.this, uri);
intent.setDataAndType(Uri.fromFile(new File(url)), "image/");
} else {
Log.i("TTSS", "startImageZoom..2");
intent.setDataAndType(uri, "image/");
}
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 100);
intent.putExtra("outputY", 100);
intent.putExtra("return-data", true);
startActivityForResult(intent, CROP_REQUEST_CODE);
}
声明:本文章只作为学习笔记的记录,如有侵权,立即删除
文章参考
解决 Android N 7.0 上 报错:android.os.FileUriExposedException
http://blog.csdn.net/yy1300326388/article/details/52787853
Android7.0适配教程,心得
http://www.jianshu.com/p/56b9fb319310