Android 5.0 動態許可權申請的基本流程和套路
注:本文主要是梳理一下Android動態許可權申請的一個基本套路。
需要有一定的Android編碼經驗,對於完全的新手來說,可能還有些技術細節沒有做具體解釋。
Android動態許可權申請有效保證了使用者的的安全,但是對開發者來說需要寫跟多的程式碼邏輯來跟使用者確認許可權。
先不考慮程式碼,我們通過官方文件的描述來梳理一下整個許可權處理的流程,如下圖:
從上圖可以看出,整個過程始於“許可權檢查”,歸集於“授權回撥”。
也就是說,除非本身就具備了相關許可權,否則我們所有的後續操作都需要從授權回撥開始往下走。
只是從授權回撥往下走的時候,需要根據前面流程所形成的的條件,進行不同的操作。
從圖中可以看出總共有三類分支(分別用紅、黃、綠三色標註):
1、使用者允許授權。
2、使用者禁止授權,且點選了“不再提示”複選框。
3、使用者禁止授權,但是沒有點選“不再提示”複選框。
那麼接下來我們就從這三種情況著手,將授權回撥的流程繼續梳理下去,如下圖:
按照谷歌的設計意圖,如果使用者拒絕了許可權,但是沒有選擇“不再提示”,我們就需要通過對話方塊等方式向用戶解釋為什麼需要授予許可權,然後再次申請許可權,彈出授權對話方塊。
如果使用者拒絕了許可權,而且選擇了“不再提示”,系統就不不會再彈出授權對話方塊。但是很多許可權都是APP執行的基本保證,所以我們還是得想辦法
我們可以看到,在授權回撥函式中時,只要是使用者使用者已經拒絕了許可權,我們都需要彈框向用戶進行許可權說明。
簡潔起見,我們完全可以把上圖中兩個自定義對話方塊的形態做到完全一樣,只是使用者點選授權後的授權不方式不一樣而已。
基於以上的完整流程分析,我們就可以設計出相應的程式碼。
此處以撥電話為例,先回顧一下上圖中谷歌的API:
1、檢測是否有許可權。
// BEGIN 動態許可權申請程式碼段 int hasCallPhonePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE); if (hasCallPhonePermission == PackageManager.PERMISSION_GRANTED) { // 有許可權,執行相關操作 callPhone(); } else { // 無許可權,需要請求許可權 ... } // END
2、請求許可權
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, CALL_PHONE_REQ);
3、授權回撥
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == CALL_PHONE_REQ) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 使用者在授權對話方塊中授予了許可權,執行相關操作
callPhone();
} else {
// 沒有授權
if (ActivityCompat.shouldShowRequestPermissionRationale(
MainActivity.this, Manifest.permission.CALL_PHONE)) {
// 沒有點選“不再提示”
showPermissionDialog(FLAG_REQUEST_PERMISSION);
} else {
// 點選了“不再提示”
showPermissionDialog(FLAG_SETTINGS_PERMISSION);
}
}
}
}
4、彈出包含說明的授權對話方塊。
private void showPermissionDialog(final int flag) {
new AlertDialog.Builder(this).setTitle("授權提示")
.setMessage("需要授予撥打電話許可權才能打電話。")
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 使用者取消了授權,整個路程結束,不執行任何操作。
Toast.makeText(MainActivity.this, "取消撥打電話", Toast.LENGTH_SHORT).show();
}
})
.setPositiveButton("去授權", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (flag) {
case FLAG_REQUEST_PERMISSION:
// 使用者之前沒有點選“不再提示”,但是此處選在繼續授權的分支
// 請求系統授權對話方塊
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CALL_PHONE}, CALL_PHONE_REQ);
break;
case FLAG_SETTINGS_PERMISSION:
// 使用者之前點選過“不再提示”,此處選擇繼續授權的分支
// 到APP的詳情頁手動授權。
startActivity(getAppDetailSettingIntent());
break;
}
}
}).create().show();
}
5、跳轉到當前APP的應用詳情頁的Intent構造。
private Intent getAppDetailSettingIntent() {
Intent localIntent = new Intent();
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
localIntent.setData(Uri.fromParts("package", getPackageName(), null));
return localIntent;
}
以上,與大家分享,希望能幫不太熟悉的朋友更清晰的梳理動態許可權申請的整個流程。