Android 權限(Permission)控制

#Working with System Permissions筆記

#Declaring Permissions
在Manifest裏聲明的權限,不涉及用戶隱私的權限,系統自動授權,設計隱私的權限,系統會詢問用戶,讓用戶授權。

Android5.1和更低版本,用戶在安裝時給app授權,包括涉及用戶隱私的權限;Android6.0和更高版本涉及用戶隱私的權限在運行時授權。

App只需要直接執行相關動作的權限。比如,app需要獲取聯絡人電話,需要READ_CONTACTS權限,但是通過intent請求Contact app獲取聯絡人電話,不需要任何權限,但是,Contact app需要這個權限。

#Requesting Permissions at Run Time
Android6.0開始,用戶可以在Settings裏取消應用權限。

系統權限分爲兩類,normal和dangerous:

  • normal權限不直接對用戶隱私造成危險,在manifest文件中聲明,系統自動授權。
  • dangerous權限能夠接觸到用戶機密數據,在manifest文件聲明,用戶還必須顯示授權。

系統版本和target SDK對權限聲明的影響:

  • 如果設備運行的是Android 5.1或更低版本,或者target SDK是22或更低:dangerous權限在app安裝過程授權,不授權不能安裝app。
  • 如果設備運行Android 6.0或更高版本,並且target SDK是23或者更高:dangerous權限在運行時授權。

注意:從Android 6.0開始(API level 23),用戶可以隨時撤銷權限,即使app target SDK低於23.

檢查權限:

// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.WRITE_CALENDAR);

用戶之前拒絕授權,之後又使用需要該權限的功能,可以通過shouldShowRequestPermissionRationable()方法判斷是否要對權限作出解釋。如果之前請求該權限被拒絕,這個方法返回true。

注意:如果用戶拒絕授權並且選擇Don’t ask again,這個方法返回false。設備禁止app使用某個權限也返回false。

請求權限:

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {

    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {

        // Show an explanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
}

處理權限請求結果

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

permission group:權限組,如果請求權限組中的某個權限,用戶同意授權,那麼之後再請求同一權限組的其他權限,系統自動授權。比如用戶同意授權READ_CONTACTS,之後請求WRITE_CONTACTS權限,系統自動授權。最好,對每個權限都顯示請求,就算是同一組的權限,而且之後的發佈版本權限組可能會發生改變。

#Permissions Usage Notes
按組列出權限:

$ adb shell pm list permission -d -g

選項-d表示dangerous權限,-g表示按組列出。

同意授權或撤銷授權:

$ adb shell pm [grant|revoke] <permission-name> ...
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章