天天看點

Android 運作時權限

半年前換過手機之後,就發現許多軟體在安裝之後已經授權過的内容,實際使用的過程中,會再次向我詢問權限。這幾天在開發的過程中,也遇到了明明在AndroidManifest.xml檔案中申請過權限了,可是程式依舊抛錯,沒有權限的問題。調查以後發現,Android在6.0系統中引用了運作時權限這個功能,從來更好的保護使用者的安全和隐私。

Android将權限歸為兩類,一類是普通權限,一類是特殊權限。對于不會威脅到使用者安全和隐私的普通權限,系統會自動幫我們進行授權,對于危險權限,必須使用者授權。以下是危險權限:

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版