圖片選擇器(相容6.0及7.0版本)
1、Android6.0 引入了一個新的應用許可權模型,期望對使用者更容易理解,更易用和更安全。所以導致拍照、讀取相簿需要動態申請許可權,直接在清單檔案manifest新增是無效的;
解決方法:
// 跳轉到系統照相機 try { Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) { // 設定系統相機拍照後的輸出路徑 // 建立臨時檔案 mTmpFile = FileUtils.createTmpFile(getActivity()); cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTmpFile)); startActivityForResult(cameraIntent, REQUEST_CAMERA); } else { Toast.makeText(getActivity(), R.string.msg_no_camera, Toast.LENGTH_SHORT).show(); } } catch (Exception e) { ToastUtils.show(getActivity(),"拍照許可權被禁用,請進入系統設定開啟許可權"); ActivityCompat.requestPermissions(getActivity(), new String[]{android.Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE,}, 123); e.printStackTrace(); }
Android6.0其實就是使用了動態申請許可權:ActivityCompat.requestPermissions(getActivity(), new String[]{android.Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE,}, 123);
這裡的話使用迭代,使用try..catch..;拋異常說明沒許可權就動態申請,授權後正常,如果拒絕後提示需要開啟許可權,並申請;
2、做專案的時候以為沒問題,相容了6.0系統就上線了;結果臥槽市場上出來了一大波Android7.0系統機子導致客戶反饋說有部分機型不能使用拍照。下面說下Android7.0,從Android6.0引入的動態許可權控制(Runtime Permissions)到Android7.0的“私有目錄被限制訪問”;因為不能訪問私有目錄結果導致拍照不能拿到返回的圖片路徑;
解決方法:
// 跳轉到系統照相機
try {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {
// 設定系統相機拍照後的輸出路徑
// 建立臨時檔案
mTmpFile = FileUtils.createTmpFile(getActivity());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(getActivity(), "com.pts80.framework.fileProvider", mTmpFile));
}else {
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTmpFile));
}
startActivityForResult(cameraIntent, REQUEST_CAMERA);
} else {
Toast.makeText(getActivity(), R.string.msg_no_camera, Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
ToastUtils.show(getActivity(),"拍照許可權被禁用,請進入系統設定開啟許可權");
ActivityCompat.requestPermissions(getActivity(), new String[]{android.Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE,}, 123);
e.printStackTrace();
}
Android7.0實際上就是不能訪問私有目錄所以我們用FileProvide:將之前Uri的scheme型別為file的Uri改成了有FileProvider建立一個content型別的Uri。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(getActivity(), "com.pts80.framework.fileProvider", mTmpFile));}else {cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTmpFile));}
這一段就是當為7.0使用FileProvider建立一個content型別的Uri;
3、我還是天真的以為可以了,並且測試了7.0機子;好一段時間沒問題,Android太多人改系統了,這點比較煩;沒辦法要相容;問題:開啟相簿直接閃退,找了下原因,發現還是許可權問題。現在是讀取已有相簿也要動態申請許可權,最後找到入口。
解決辦法:
// 首次載入所有圖片
// new LoadImageTask().execute();
try {
getActivity().getSupportLoaderManager().initLoader(LOADER_ALL, null, mLoaderCallback);
}catch (Exception e){
ToastUtils.show(getActivity(),"相簿許可權被禁用,請進入系統設定開啟許可權");
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE,}, 123);ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE,}, 123);
e.printStackTrace();
}