最近項目中用到調用相機相冊并裁剪的功能點,之前的代碼在系統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,整體過程就是這樣的。