FileUriExposedException,7.0解决办法
背景:打开相机拍一张照片,回来后剪切,然后上传
1.使用ContentProvider方式传递uri
if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.N) {
ContentValues contentValues =newContentValues(1);
contentValues.put(MediaStore.Images.Media.DATA,mFile.getAbsolutePath());
mUri=mContext.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues);
}else{
mUri= Uri.fromFile(mFile);
}
Intent intent =newIntent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,mUri);//这句一定要有
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY,1);
startActivityForResult(intent,CODE_CAMERA);
file路径
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
if(!file.exists()){file.mkdirs();}
mFile=newFile(file, System.currentTimeMillis() +".jpg");
然后在onActivityResult里判断相机返回
if( resultCode ==RESULT_OK) {
startPhotoZoom1(mUri);//打开裁剪界面,uri为上面的
}
/**
*打开系统图片裁剪功能,7.0版本
*@paramuri
*/
private voidstartPhotoZoom1(Uri uri) {
Intent intent =newIntent("com.android.camera.action.CROP");
intent.setDataAndType(uri,"image/*");
intent.putExtra("crop",true);
intent.putExtra("aspectX",1);
intent.putExtra("aspectY",1);
intent.putExtra("outputX",300);
intent.putExtra("outputY",300);
intent.putExtra("scale",true);//黑边
intent.putExtra("scaleUpIfNeeded",true);//黑边
intent.putExtra("return-data",true);
intent.putExtra("noFaceDetection",true);
intent.putExtra(MediaStore.EXTRA_OUTPUT,mUri);//没有这句报无法加载图片
startActivityForResult(intent,REQUESTCODE_CUT);
}
然后在onActivityResult里判断剪切返回
Bundle bundle = data.getExtras();
if(bundle !=null){
mBitmap= bundle.getParcelable("data");
saveBitmap(mBitmap);
}
/**保存方法*/
public voidsaveBitmap(Bitmap bm) {
File f =newFile(this.getFilesDir(), (newDate()).getTime()+".png");
if(f.exists()) {f.delete();}
try{
FileOutputStream out =newFileOutputStream(f);
bm.compress(Bitmap.CompressFormat.PNG,90, out);
out.flush();
out.close();
}catch(FileNotFoundException e,IOException ee) {
e.printStackTrace();
f =null;
}
if(f !=null) {
mPresenter.httpUploadPic(f.getPath());//我的上传方法
}
}
方法2:通过FileProvider解决
先在manifest中声明一个provider如下.
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.ztrk.apgold.fileprovider"//此处为自定义名,最好为包名
android:exported="false"
android:grantUriPermissions="true">
<meta_data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />//file_paths编写该Provider对外提供文件的目录,文件放置在res/xml/下
</provider>
然后编写file_paths.xml
<paths>
<files-path name="name" path="path"/>//files-path对应Context.getFilesDir(),path为下级路径
<cache-path name="name" path="path"/>//cache-path对应Context.getCacheDir()
<external-path name="name" path="path" />//external-path对应Environment.getExternalStorageDirectory()
<external-files-path name="name" path="path" /> //external-files-path对应Context.getExternalFilesDir()
<external-cache-path name="name" path="path" />//external-cache-path对应Context.getExternalCacheDir()
//这五个可写一个或多个
</paths>
java代码
Uri uri = FileProvider.getUriForFile(context, "com.ztrk.apgold.fileprovider", file); //第二个参数是manifest中定义的`authorities`,,file为文件对象
Intent intent =newIntent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //这一步很重要。给目标应用一个临时的授权。
intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);//这句一定要有
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY,1);
startActivityForResult(intent,CODE_CAMERA);
然后在onActivityResult里判断相机返回,剩下同方法1
PS:如果打开相机时闪退,可以看一下应用权限的存储打开没有