Android 6.0以上許可權處理
最近在開發過程中,遇到適配Android 6.0及以上版本的許可權處理問題。
一、問題背景
通常,在6.0以上版本,僅僅只在AndroidManifest.xml檔案中配置許可權,有很多情況下,許可權並沒有獲得到,而是丟擲了異常:
java.lang.SecurityException: Permission Denial:
或者是:
java.lang.SecurityException: was not granted this permission:
表示你需要的許可權被拒絕或者沒有授權。
出現這種異常的,通常是要使用一些特殊的、敏感的許可權。Android 6.0以上做了相關規定,此類許可權需要使用者動態授權。
Google 對Android 6.0進行了規定:
許可權分為Normal Permission、Dangerous Permission兩類。
(1) 對於Normal Permission扔按照低版本的設定方式,直接在AndroidManifest.xml檔案中直接< user-permission name=”android.permission.許可權名”/> 標籤中設定即可。
(2)對於Dangerous Permission則需要動態申請授權!
二、處理問題的姿勢
1.以申請撥打電話android.permission.CALL_PHONE許可權為例。
(1) 在AndroidManifest檔案中新增需要的許可權。
這個步驟不能省略,試圖去申請一個沒有宣告的許可權可能會導致程式崩潰。
(2) 檢查所需的許可權是否沒有授權。(通常有一個版本的判斷,如果是高版本,才執行)
public void method() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
checkPermission();
} else {
// 業務操作
call();
}
}
public void checkPermission() {
if (ContextCompat.checkSelfPermission(this ,
Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this ,
new String[]{Manifest.permission.CALL_PHONE},
CALL_TAG/*指定一個標記,在回撥的時候使用*/);
} else {
// 業務操作
call();
}
}
public void call() {
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber));
startActivity(intent);
}
(3) 在呼叫了上述的 requestPermission() 方法後,系統會彈出一個供使用者授權的對話方塊。
這個對話方塊由使用者選擇後,會呼叫許可權回撥方法:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
call();
} else {
Toast.makeText(this, "未獲得CALL_PHONE許可權", Toast.LENGTH_SHORT).show();
}
}
在此方法中,引數requestCode是呼叫requestPermissions時傳入的最後一個引數(例子中時CALL_TAG)
引數permissions是請求授權的許可權陣列
引數grantResult是對應許可權的授權結果,0表示授權成功,-1表示拒絕授權。
在此方法中可以用requestCode判斷,多許可權可以用迴圈遍歷permissions/grantResult陣列等方式。