Android运行时权限

在Android6.0以后,Google将权限分为了两类,一类为正常权限(Normal Permission),一类为危险权限(Dangerous Permission)。对于正常正常权限,只需在Manifest文件里面申请即可,但对于危险权限,需要运行时动态申请。

危险权限包括以下:

权限组权限
group:android.permission-group.CONTACTSpermission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
group:android.permission-group.PHONEpermission: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.CALENDARpermission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR
group:android.permission-group.CAMERApermission:android.permission.CAMERA
group:android.permission-group.SENSORSpermission:android.permission.BODY_SENSORS
group:android.permission-group.LOCATIONpermission:android.permission.ACCESS_FINE_LOCATION
permission:android.permission.ACCESS_COARSE_LOCATION
group:android.permission-group.STORAGEpermission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE
group:android.permission-group.MICROPHONEpermission:android.permission.RECORD_AUDIO
group:android.permission-group.SMSpermission: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");
        }
    }

td

相关推荐