在Android6.0以後,Google將許可權分為了兩類,一類為正常許可權(Normal Permission),一類為危險許可權(Dangerous Permission)。對於正常正常許可權,只需在Manifest文件裡面申請即可,但對於危險許可權,需要運行時動態申請。 危險許可權包括以下: 動態許可權申請 ...
在Android6.0以後,Google將許可權分為了兩類,一類為正常許可權(Normal Permission),一類為危險許可權(Dangerous Permission)。對於正常正常許可權,只需在Manifest文件裡面申請即可,但對於危險許可權,需要運行時動態申請。
危險許可權包括以下:
許可權組 | 許可權 |
---|---|
group:android.permission-group.CONTACTS | permission:android.permission.WRITE_CONTACTS permission:android.permission.GET_ACCOUNTS permission:android.permission.READ_CONTACTS |
group:android.permission-group.PHONE | permission:android.permission.READ_CALL_LOG permission:android.permission.READ_PHONE_STATE permission:android.permission.CALL_PHONE permission:android.permission.WRITE_CALL_LOG permission:android.permission.USE_SIP permission:android.permission.PROCESS_OUTGOING_CALLS permission:com.android.voicemail.permission.ADD_VOICEMAIL |
group:android.permission-group.CALENDAR | permission:android.permission.READ_CALENDAR permission:android.permission.WRITE_CALENDAR |
group:android.permission-group.CAMERA | permission:android.permission.CAMERA |
group:android.permission-group.SENSORS | permission:android.permission.BODY_SENSORS |
group:android.permission-group.LOCATION | permission:android.permission.ACCESS_FINE_LOCATION permission:android.permission.ACCESS_COARSE_LOCATION |
group:android.permission-group.STORAGE | permission:android.permission.READ_EXTERNAL_STORAGE permission:android.permission.WRITE_EXTERNAL_STORAGE |
group:android.permission-group.MICROPHONE | permission:android.permission.RECORD_AUDIO |
group:android.permission-group.SMS | permission:android.permission.READ_SMS permission:android.permission.RECEIVE_WAP_PUSH permission:android.permission.RECEIVE_MMS permission:android.permission.RECEIVE_SMS permission:android.permission.SEND_SMS permission:android.permission.READ_CELL_BROADCASTS |
動態許可權申請:
1、在manifest文件裡面配置所有需要申請的許可權(包括普通許可權和危險許可權)
2、確保工程TargetSdkVersion版本在23以上(因為動態許可權是針對23以上的版本設計的,如果TargetSdkVersion低於23,相關介面將會失效,比如ActivityCompat.checkSelfPermission將始終返回0)
3、確保目標設備為Android6.0及以上
4、檢查許可權:ActivityCompat.checkSelfPermission檢查許可權是否被允許。如果許可權被拒絕,在使用ActivityCompat.shouldShowRequestPermissionRationale檢查許可權是否被徹底拒絕。
5、許可權申請:如果許可權沒有被徹底拒絕,則可以使用ActivityCompat.requestPermissions申請許可權
6、後續處理:當用戶處理完許可權請求後,可以通過onRequestPermissionsResult獲取到用戶處理的結果
示例代碼:
檢查TargetSdkVersion和目標設備API版本:
private static int getTargetSdkVersion(Activity activity){ int targetSdkVersion = 0; Context context = activity.getApplicationContext(); try { final PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); targetSdkVersion = info.applicationInfo.targetSdkVersion; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return targetSdkVersion; } private static boolean checkRuntimePermissionAvailable(Activity activity){ // Always return true for API version < M, let the system deal with the permissions if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { Log.w("Permission", "API version < M, return true by default"); return false; } // Always return true for target sdk version < M, let the system deal with the permissions if (getTargetSdkVersion(activity) < Build.VERSION_CODES.M) { Log.w("Permission", "Target sdk version < M, return true by default"); return false; } return true; }
獲得被拒絕的許可權:
@SuppressLint("NewApi") private static String[] getDeniedPermissions(Activity activity, String[] permissions, boolean isAll) { List<String> deniedPermissionList = new ArrayList<String>(); Context context = activity.getApplicationContext(); for (String permission : permissions){ if (ActivityCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED){ Log.i("Permission", "\"" + permission + "\" has been granted"); } else { if (ActivityCompat.shouldShowRequestPermissionRationale(thisClass, permission)){ deniedPermissionList.add(permission); Log.w("Permission", "\"" + permission + "\" was denied"); }else{ if (isAll){ deniedPermissionList.add(permission); } Log.w("Permission", "\"" + permission + "\" was denied completely"); } } } String[] deniedPermissions = new String[deniedPermissionList.size()]; deniedPermissions = deniedPermissionList.toArray(deniedPermissions); return deniedPermissions; }
申請被拒絕的許可權:
@SuppressLint("NewApi") private static void requestPermissions(Activity activity, int requestCode, String[] deniedPermissions){ for( String permission : deniedPermissions ){ Log.i("Permission", "Requesting permission \"" + permission + "\""); } ActivityCompat.requestPermissions(activity, deniedPermissions, requestCode); }
許可權申請的後續處理:
@SuppressLint("NewApi") public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { // TODO Auto-generated method stub super.onRequestPermissionsResult(requestCode, permissions, grantResults); boolean isAllGranted = true; switch( requestCode ){ case 1: for ( int result : grantResults){ if (result != PackageManager.PERMISSION_GRANTED){ isAllGranted = false; break; } } break; } if (isAllGranted){ // All permissions are granted Log.i("Permission", "All permissions have been granted"); }else{ // There is at least a permission which aren't granted Log.w("Permission", "There is at least a permission which aren't granted"); } }