最近项目中用到调用相机相册并裁剪的功能点,之前的代码在系统6.0和7.0上出现了问题,全是权限的坑,现在将适配好的代码粘贴出来,作为备忘吧。
在系统6.0以后需要添加运行时权限相关代码 比如在出现选择相机还是相册的dialog之前申请权限:
//6.0以上系统申请定位权限
申请权限的回调为:
在manifest中添加:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="包名.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
在res下创建目录,增加provider_paths.xml
provider_paths.xml文件的内容为:
当通过弹出的dialog选择相机时调用selectFromCamera方法:
其中getUriForFile(context,file)方法为:
当选择相册的时候调用:
当调用裁剪时:
Uri mCropUri;
public void startPhotoZoom(Uri uri, int targetW, int targetH) {
Intent intent = new Intent("com.android.camera.action.CROP");
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
String url = FileUtils.getPath(QuickApplication.getInstance(), uri);
intent.setDataAndType(getUriForFile(mAct,new File(url)), "image/*");
} else {
intent.setDataAndType(uri, "image/*");
}
// crop为true是设置在开启的intent中设置显示的view可以剪裁
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", targetW);
intent.putExtra("aspectY", targetH);
// outputX,outputY 是剪裁图片的宽高
intent.putExtra("outputX", targetW);
intent.putExtra("outputY", targetH);
intent.putExtra("scale", true);
intent.putExtra("return-data", false);
intent.putExtra("noFaceDetection", true);
getCutUri();
intent.putExtra(MediaStore.EXTRA_OUTPUT, mCropUri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
|Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
mAct.startActivityForResult(intent, Constants.REQUEST_CODE_CREATE_FROM_CROP);
}
private void getCutUri() {
File file =newFile(SdcardUtil.getPhotoCacheDir(), FileUtils.getPhotoFileName());
mCropUri= Uri.fromFile(file);
}
最后的mCropUri为裁剪之后的图片uri,整体过程就是这样的。