Android 权限管理 与 EasyPermissions使用

官网链接

https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous%29

Android 6.0(API 23)之后,加强了权限管理,现整理一下相关变化,如下。

权限组 permission-group

给相关的权限声明一个逻辑上的分组名称;
同一分组的中成员会一起展现在用户的界面中;
同一组的任何一个权限被授权了,其他权限也自动被授权;
例如,一旦READ_EXTERNAL_STORAGE 被授权了,则App也有WRITE_EXTERNAL_STORAGE权限。

权限级别

normal 低风险权限

只要申请了就可以使用(在AndroidManifest.xml中添加标签),安装时不需要用户确认;

dangerous 高风险权限

安装时需要用户的确认才可使用;
查看高风险权限可以使用如下adb 命令:

adb shell pm list permissions -d -g

结果如下图:

Dangerous Permissions:

group:com.google.android.gms.permission.CAR_INFORMATION
  permission:com.google.android.gms.permission.CAR_VENDOR_EXTENSION
  permission:com.google.android.gms.permission.CAR_MILEAGE
  permission:com.google.android.gms.permission.CAR_FUEL

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.ANSWER_PHONE_CALLS
  permission:android.permission.READ_PHONE_NUMBERS
  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:com.google.android.gms.permission.CAR_SPEED
  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

ungrouped:
  permission:com.google.android.providers.talk.permission.WRITE_ONLY
  permission:com.google.android.providers.talk.permission.READ_ONLY

注:上述这些权限是需要在运行时申请的。

signature 签名权限

只有当申请权限的应用程序的数字签名与声明此权限的应用程序的数字签名相同时(如果是申请系统权限,则需要与系统签名相同),才能将权限授给它;

权限适配

Normal 低风险权限

在AndroidManifest.xml文件里申请,App安装时会默认获得这些权限;
即使是在Android6.0系统的手机上,用户也无法在安装后取消这些Normal权限;
和以前的处理是一样的,不变;

Dangerous 高风险权限

也需要在AndroidManifest.xml文件里申请,但是App安装时具体如果执行授权分以下几种情况:
1、targetSDKVersion < 23 & API(手机系统) < 6.0
安装时默认获得权限,且用户无法在安装App之后取消权限;

2、targetSDKVersion < 23 & API(手机系统) >= 6.0
安装时默认获得权限,但是用户可以在安装App完成后动态取消授权( 取消时手机会弹出提醒,告诉用户这个是为旧版手机打造的应用,让用户谨慎操作 )

3、targetSDKVersion >= 23 & API(手机系统) < 6.0
安装时默认获得权限,且用户无法在安装App之后取消权限;

4、targetSDKVersion >= 23 & API(手机系统) >= 6.0
安装时不会获得权限,可以在运行时向用户申请权限。用户授权以后仍然可以在设置界面中取消授权,用户主动在设置界面取消后,在app运行过程中可能会出现crash

EasyPermission

EasyPermission库是一个谷歌官方提供的简化基本的系统权限逻辑的库,可用于在Android M或者更高版本上;

项目官网地址如下:https://github.com/googlesamples/easypermissions

0、引入依赖

dependencies {
    // For developers using AndroidX in their applications
    implementation 'pub.devrel:easypermissions:3.0.0'
 
    // For developers using the Android Support Library
    implementation 'pub.devrel:easypermissions:2.0.1'
}

1、检查权限

权限可以是单个,也可以是一些列;
在EasyPermission库中,使用hasPermissions() 检查若干权限;

  String[] PERMS = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
  if (!EasyPermissions.hasPermissions(BaseActivity.this, PERMS)) {
      // 没有权限,进行权限请求
  }

第一个参数 : Context参数;
第二个参数 : 一些系列的权限,可以是单个,也可以是一组;

2、请求权限

检查权限后,发觉用户没有赋予权限,这时候需要代码请求权限,让用户同意;
在EasyPermission库中,使用requestPermissions(),来请求权限;

  String[] PERMS = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
  final int PERMS_CODE = 55;
  if (!EasyPermissions.hasPermissions(BaseActivity.this, PERMS)) {
     // 没有权限,进行权限请求
     EasyPermissions.requestPermissions(this, "为了正常使用App,请为App授权", PERMS_CODE, PERMS);
}

第一个参数:Context对象;
第二个参数:权限弹窗上的文字提示语,告诉用户,这个权限用途;
第三个参数:这次请求权限的唯一标示;
第四个参数 : 一些系列的权限;

3、响应请求结果

请求后,弹出系统权限弹窗,剩下是用户是否授权操作;
权限结果是回调在Activity或者Fragment中的重写的onRequestPermissionsResult()方法中;

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        // 将结果转发给 EasyPermissions
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    /**
     * 请求权限成功。
     * 可以弹窗显示结果,也可执行具体需要的逻辑操作
     *
     * @param requestCode
     * @param perms
     */
    @Override
    public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
        ToastUtils.showMsg(this, "用户授权成功");
    }

    /**
     * 请求权限失败
     *
     * @param requestCode
     * @param perms
     */
    @Override
    public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
        ToastUtils.showMsg(this, "用户授权失败");

        //若是在权限弹窗中,用户勾选了'NEVER ASK AGAIN.'或者'不在提示',且拒绝权限。
        //这时候,需要跳转到设置界面去,让用户手动开启。
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            new AppSettingsDialog.Builder(this).build().show();
        }
    }

将权限结果传递给EasyPermissions.onRequestPermissionsResult()来处理;
EasyPermissions.onRequestPermissionsResult()方法:
第一个参数: 请求的code
第二个参数: 一些列的请求权限
第三个参数: 用户授权的结果
第四个参数: 权限回调监听器

这里不需要手写判断权限是否成功的逻辑操作,而会在EasyPermissions.PermissionCallbacks监听器中响应;
EasyPermissions.PermissionCallbacks接口:
①onPermissionsGranted():用户授权成功,接下来执行具体需要的逻辑操作;
②onPermissionsDenied():用户授权失败,处理失败的逻辑;

4、处理权限被拒的情况

在权限弹窗中,用户可能直接拒绝权限,下次权限请求依旧会弹出该权限弹窗。除此之外,还可以勾选’NEVER ASK AGAIN.’或者’不再提示’,且拒绝权限,下次请求权限,弹窗不能弹出,无法让用户授权。这时候,需要跳转到设置界面去,让用户手动开启。

在EasyPermission库中,使用EasyPermissions.somePermissionPermanentlyDenied()来处理,是否勾选不再提示的选项。

/**
     * 请求权限失败
     *
     * @param requestCode
     * @param perms
     */
    @Override
    public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
        ToastUtils.showMsg(this, "用户授权失败");

        //若是在权限弹窗中,用户勾选了'NEVER ASK AGAIN.'或者'不在提示',且拒绝权限。
        //这时候,需要跳转到设置界面去,让用户手动开启。
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            new AppSettingsDialog.Builder(this).build().show();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            //当从软件设置界面,返回当前程序时候
            case AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE:
                //执行Toast显示或者其他逻辑处理操作
                ToastUtils.showMsg(this, "从设置界面返回了!");
                break;
        }
    }

当无法弹出权限弹框,直接跳转到设置界面去,让用户手动开启权限;
当从设置界面返回时候,结果会在Activity或者Fragment中onActivityResult()响应;

你可能感兴趣的:(Android,#,Android基础,Android6,危险权限,权限组,动态权限,EasyPermissions)