今天將項目中需要授權的地方,增加了判斷 -----------關於6.0權限的封裝。
大家知道,在android6.0之後,谷歌爲了更進一步保護用戶的手機安全及知情權,在權限管理方面做了改變。
在6.0之前,我們只需要在Manifest裏增加對應的權限標籤即可,
如:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
但是現在就不同了,比如調用照相機。用戶的系統設置默認不授予你的應用這個權限,而你此時沒有進行動態授權,
那不同產商就會有不同的問題(輕則不能調用,重則直接崩潰,小編的小米就是直接崩)
說了這麼多,讓我們看看代碼。
在BaseActivity做好封裝,具體的子類只要進行調用,去實現具體的邏輯就好
四部曲:
第一步,先判斷是否有權限
/**
* 判斷是否擁有權限
*
* @param permissions
* @return
*/
public boolean hasPermission(String... permissions) {
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED)
return false;
}
return true;
}
//說明:
//String... permissions
//形參String...的效果其實就和數組一樣,這裏的實參可以寫多個String,也就是權限(下面講到友盟分享的權限申請時就會理解)
第二步:如果沒有權限,就進行請求
/**
* 請求權限
*/
protected void requestPermission(int code, String... permissions) {
ActivityCompat.requestPermissions(this, permissions, code);
ToastUtil.showMessage(this, "如果拒絕授權,會導致應用無法正常使用", Toast.Length_SHORT);
}
第三步:請求授權後的回調
/**
* 請求權限的回調
*
* @param requestCode
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case Constants.CODE_CAMERA:
//例子:請求相機的回調
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
ToastUtil.showMessage(this, "現在您擁有了權限");
// 這裏寫你需要的業務邏輯
doYourNeedDo();
} else {
ToastUtil.showMessage(this, "您拒絕授權,會導致應用無法正常使用,可以在系統設置中重新開啓權限", Toast.Length_SHORT);
}
break;
case Constants.CODE_READ_EXTERNAL_STORAGE:
//另一個權限的回調
break;
}
}
//說明:
//Constants.CODE_CAMERA
//這是在外部封裝的一個常量類,裏面有許多靜態的URL以及權限的CODE,可以自定義
//但是在調用的時候,記得這個CODE要和你自己定義的CODE一一對應
最後,第四步,留一個方法,給子類重寫,實現你所需要的業務邏輯(比如 拍照)
//子類重寫後實現具體調用相機的業務邏輯
public void doYourNeedDo() {
//留給子類重寫,這裏空白就好
}
OK,封裝完成
接下來,在需要進行授權的Activity中 extends 這個封裝了權限請求的BaseActvity
在需要調用的地方進行判斷
//判斷是否有權限
if (hasPermission(Manifest.permission.CAMERA,Manifest.permission.CAMERA)) {
//有權限,則寫你的業務邏輯
doYourNeedDo();
}else {
//沒權限,進行權限請求
requestPermission(Constants.CODE_CAMERA, Manifest.permission.CAMERA);
}
//重寫調用相機的邏輯
@Override
public void doYourNeedDo() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 拍照後保存圖片的絕對路徑
String cameraPath = LocalImageHelper.getInstance().setCameraImgPath();
File file = new File(cameraPath);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(intent, ImageUtils.REQUEST_CODE_GETIMAGE_BYCAMERA);
}
OK,這樣就搞定了。
寫到這裏,總結一下上面的思路,
就是,
一,判斷權限、
二、有權限,執行 / 沒權限,請求權限
三、請求後的權限回調(這裏注意CODE,要匹配)
四、業務邏輯(有權限則直接從第二步跳到這步,沒權限則在第三步的回調中調用)
上面的封裝方法,最好在Manifest裏還是像原先一樣,將需要的權限先添加上,這樣就可以兼容6.0以上和6.0以下的版本。
6.0以下不會有任何影響。
再說一說友盟的實現邏輯
//如想讓你的app在android 6.0系統上也能運行的話,需要動態獲取權限,沒有權限的話分享sdk會出錯,
//參考一下代碼做動態獲取權限,適配安卓6.0系統
//你需要最新的android.support.v4包,或者v13的包可也以
if(Build.VERSION.SDK_INT>=23){
String[] mPermissionList = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.CALL_PHONE,Manifest.permission.READ_LOGS,Manifest.permission.READ_PHONE_STATE, Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.SET_DEBUG_APP,Manifest.permission.SYSTEM_ALERT_WINDOW,Manifest.permission.GET_ACCOUNTS,Manifest.permission.WRITE_APN_SETTINGS};
ActivityCompat.requestPermissions(this,mPermissionList,123);
}
其實思路大抵相同,只是友盟是通過判斷版本號,是否大於23,。
上面這段代碼是直接從友盟分享中拷出來的,mPermissionList 這個數組用在我們第一種封裝的方法上也是一樣的。
大功告成,
週五下班,可憐的上了兩天班的小編要準備過週末了, 本文可能會有一些細小謬誤,下週一回來改。
祝各位小夥伴國慶玩的愉快,勇敢的迎接補班的日子吧!哈哈