Android6.0發(fā)布這么久贝润,對運行時權限也看了很多資料绊茧,對比過幾個流行的庫。但是個人還是喜歡在項目里用自己動手封裝的東西打掘,哪怕照抄也好华畏。。尊蚁。不知道是什么原因亡笑。
前天無意聽郭神的直播。講解的是運行時權限的封裝横朋,收益頗多仑乌。依樣畫葫蘆,記錄下來琴锭,沒看直播的同學也可以看看(郭神的第二行代碼已經當工具書了晰甚,每次翻開看到郭神的簽名,都覺得真的是字如其人决帖。厕九。。)
前陣子封裝個基類庫地回,快捷開發(fā)可以直接用扁远,運行時權限正好整合進去腺阳。開始:
Permission,運行時權限
授權權限
*如果設備運行的是Android 6(API Level 23)或更高,和應用程序的targetSdkVersion是23或更高穿香,應用程序要求的權限由用戶在運行時亭引。用戶可以在任何時間撤銷權限,所以在每次運行時應用程序需要檢查是否有權限皮获。
如果設備運行的是Android 5.1(API Level 22)或更低焙蚓,或應用程序targetSdkVersion等于或低于22時,當用戶安裝的應用程序洒宝,系統會要求用戶授予權限购公。用戶的應用程序更新,如果你添加一個新的權限的應用程序的更新版本雁歌,系統會要求用戶授予權限時宏浩。一旦用戶安裝該應用程序,他們可以撤銷許可的唯一途徑是通過卸載應用程序靠瞎。
拒絕權限
*每當一個權限被拒絕應向用戶解釋使用該權限的具體用途比庄,保證功能要求的權限總是行為為目的,應用程序應該說是需要許可乏盐,允許它提供了一種方法佳窑。而權限被拒絕的途徑以下兩種:
由用戶拒絕權限請求
用戶選擇過“不要再問”,用戶權限是默默的否認父能,沒有警告
封裝
申請權限后腰毀掉給當前activity神凑,所以先定義一個回掉接口PermissionListener
public interface PermissionListener { //授權成功 void onGranted(); //授權部分 void onGranted(List<String> grantedPermission); //拒絕授權 void onDenied(List<String> deniedPermission); }
在BaseActivity里寫授權申請,首先檢查申請的權限是不是被授權了,如果不是就加入待授權數組里何吝,去申請權限溉委。如果全部已授權,就直接回掉授權成功爱榕。
/** 權限申請
* @param permissions
* @param listener
*/
protected void requestRunTimePermission(String[] permissions, PermissionListener listener) {
//todo 獲取棧頂activity瓣喊,如果null。return呆细;
this.mPermissionListener = listener;
List<String> permissionList = new ArrayList<>();
for (String permission : permissions) {
if(ContextCompat.checkSelfPermission(this,permission)!= PackageManager.PERMISSION_GRANTED){
permissionList.add(permission);
}
}
if(!permissionList.isEmpty()){
ActivityCompat.requestPermissions(this,permissionList.toArray(new String[permissionList.size()]),1);
}else{
listener.onGranted();
}
}
然后重寫授權返回方法型宝。系統會返回2個數組, String[] permissions是你申請的權限絮爷,int[] grantResults是授權結果。拿出授權結果比對梨树,如果授權坑夯,加入授權數組,如果拒絕抡四,加入拒絕數組柜蜈≌套唬回掉給注冊PermissionListener的activity
/** 申請結果
* @param requestCode
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case 1:
if (grantResults.length>0){
List<String> deniedPermissions = new ArrayList<>();
List<String> grantedPermissions = new ArrayList<>();
for (int i = 0; i < grantResults.length; i++) {
int grantResult = grantResults[i];
if (grantResult != PackageManager.PERMISSION_GRANTED){
String permission = permissions[i];
deniedPermissions.add(permission);
}else{
String permission = permissions[i];
grantedPermissions.add(permission);
}
}
if (deniedPermissions.isEmpty()){
mPermissionListener.onGranted();
}else{
mPermissionListener.onDenied(deniedPermissions);
mPermissionListener.onGranted(grantedPermissions);
}
}
break;
}
}
然后你的實現了BaseActivity的activity實現PermissionListener,需要申請權限的地方調用requestRunTimePermission(permissions淑履,this);在回掉方法里根據結果實現邏輯隶垮。
附:
權限可以分為危險權限和正常權限,還有特殊權限秘噪、自定義權限狸吞。
正常權限(PROTECTION_NORMAL)對用戶的隱私或安全沒有大的風險的權限在AndroidManifest.xml聲明里,如果應用需要一個正常的權限指煎,在安裝的時候系統自動授予該權限蹋偏。在使用的時候系統不提示用戶,用戶也不能撤銷這些權限至壤。
危險權限威始,需要使用時要檢查有沒有授權。如果沒有就彈個對話框詢問用戶授權像街。這類權限被分組了黎棠,同一組的任何一個權限被授權了,其他權限也自動被授權镰绎。如下表:
比如你需要android.permission.READ_CONTACTS 葫掉,去讀聯系人。這個權限被用戶授權跟狱,然后你用到寫入通訊錄權限permission:android.permission.WRITE_CONTACTS和permission:android.permission.GET_ACCOUNTS 時俭厚,就是授權過的,去申請就不會彈框驶臊。
don't worry be happy