半年前換過手機之後,就發現許多軟體在安裝之後已經授權過的内容,實際使用的過程中,會再次向我詢問權限。這幾天在開發的過程中,也遇到了明明在AndroidManifest.xml檔案中申請過權限了,可是程式依舊抛錯,沒有權限的問題。調查以後發現,Android在6.0系統中引用了運作時權限這個功能,從來更好的保護使用者的安全和隐私。
Android将權限歸為兩類,一類是普通權限,一類是特殊權限。對于不會威脅到使用者安全和隐私的普通權限,系統會自動幫我們進行授權,對于危險權限,必須使用者授權。以下是危險權限:
比如,我們需要申請讀寫存儲檔案的權限,可以這麼申請:
String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE , Manifest.permission.READ_EXTERNAL_STORAGE};
List<String> mPermissionList = new ArrayList<String>();
for (int i = 0; i < permissions.length; i++) {
if (ContextCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
mPermissionList.add(permissions[i]);
}
}
if (mPermissionList.isEmpty()) {
return;
}
String[] permissionArray = mPermissionList.toArray(new String[mPermissionList.size()]);
ActivityCompat.requestPermissions(this, permissionArray, 1);
如果申請的隻有一個權限,也可以這麼寫:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 1);
}
注意,ActivityCompat.requestPermissions方法中的第三個參數是請求碼。
調用完畢之後,系統會彈出詢問權限是否授權的dialog,無論統一還是拒絕都會調用onRequestPermissionsResult()方法,授權結果會封裝在grantResults中。
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 1:
for (int i = 0; i < permissions.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
//判斷是否勾選禁止後不再詢問
boolean showRequestPermission = ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i]);
if (showRequestPermission) {
ActivityCompat.requestPermissions(this, new String[]{permissions[i]}, 1);
} else {
// 如果使用者在過去拒絕了權限請求,并在權限請求系統對話框中選擇了 Don’t ask again 選項,此方法将傳回 false。如果裝置規範禁止應用具有該權限,此方法也會傳回 false。
Toast.makeText(this, "請前往設定開啟權限", Toast.LENGTH_SHORT).show();
return;
}
}
}
......
break;
default:
break;
}
}
參考:第一行代碼第2版