Android运行时权限
在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");
}
}

浙公网安备 33010602011771号