#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> ...