從Android 6.0開始, 用戶需要在運行時請求權限, 本文對運行時權限的申請和處理進行介紹, 並討論了使用運行時權限時新老版本的一些處理.
Android應用權限簡要介紹
Permission的保護等級
Table 1. Dangerous permissions and permission groups.
Permission Group | Permissions |
---|---|
CALENDAR |
|
CAMERA |
|
CONTACTS |
|
LOCATION |
|
MICROPHONE |
|
PHONE |
|
SENSORS |
|
SMS |
|
STORAGE |
手機版本和程序版本的不同處理
- If the device is running Android 6.0 (API level 23) or higher, and the app's
targetSdkVersion
is 23 or higher, the app requests permissions from the user at run-time. The user can revoke the permissions at any time, so the app needs to check whether it has the permissions every time it runs. For more information about requesting permissions in your app, see the Working with System Permissions training guide. - If the device is running Android 5.1 (API level 22) or lower, or the app's
targetSdkVersion
is 22 or lower, the system asks the user to grant the permissions when the user installs the app. If you add a new permission to an updated version of the app, the system asks the user to grant that permission when the user updates the app. Once the user installs the app, the only way they can revoke the permission is by uninstalling the app.
爲什麼要及時升級targetSdkVersion
Permission group
動態權限請求的實現
1.檢查權限狀態
PERMISSION_GRANTED
if
you have the permission, or PERMISSION_DENIED
if
not.if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_CONTACTS)) { //has permission, do operation directly ContactsUtils.readPhoneContacts(this); Log.i(DEBUG_TAG, "user has the permission already!"); } else { //do not have permission
2.動態請求權限
if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_CONTACTS)) { //has permission, do operation directly ContactsUtils.readPhoneContacts(this); Log.i(DEBUG_TAG, "user has the permission already!"); } else { //do not have permission Log.i(DEBUG_TAG, "user do not have this permission!"); // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, 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. Log.i(DEBUG_TAG, "we should explain why we need this permission!"); } else { // No explanation needed, we can request the permission. Log.i(DEBUG_TAG, "==request the permission=="); ActivityCompat.requestPermissions(MainActivity.this, 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. } }
onRequestPermissionsResult()
方法,傳回用戶的響應.@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. ContactsUtils.readPhoneContacts(this); Log.i(DEBUG_TAG, "user granted the permission!"); } else { // permission denied, boo! Disable the // functionality that depends on this permission. Log.i(DEBUG_TAG, "user denied the permission!"); } return; } // other 'case' lines to check for other // permissions this app might request } }
onRequestPermissionsResult()
回調方法,
並傳回PERMISSION_GRANTED的結果.Best Practices
ADB命令
- List permissions and status by group:
$ adb shell pm list permissions -d -g
- Grant or revoke one or more permissions:
$ adb shell pm [grant|revoke] <permission-name> ...