1. 程式人生 > >圖片選擇器(相容6.0及7.0版本)

圖片選擇器(相容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();
		}