Android简单动态权限申请_EasyPermissions

Android6.0后引入新的权限机制, 对于危险权限除了在AndroidManifest声明以外还需要动态申请权限.

所谓的动态申请, 即弹出对话框让用户选择是否同意该权限.

其实每次判断权限申请权限都是重复代码. 原生的动态申请方式我就不讲了, 这里我讲下EasyPermission框架的用法, 这是Google官方的推荐框架, 该框架能够达到一行代码申请权限. 且统一处理所有权限回调结果.

对于危险权限Android 6.0会默认显示在应用信息中, 可以再次关闭或者手动允许. 也就是说危险权限提供可控开关.

危险权限列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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

通过ADB命令查看所有的危险权限的列表

1
adb shell pm list permissions -d -g

EasyPermission

添加依赖

1
compile 'pub.devrel:easypermissions:0.3.0'

该框架其实支持的方法很少, 出去重载的方法就只有四个;

  1. 判断权限
  2. 请求权限
  3. 接受权限结果
  4. 判断永久被拒绝的权限

判断权限

1
EasyPermissions.hasPermissions(...)

请求权限

1
EasyPermissions.requestPermissions(...);

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
String locationPermission = Manifest.permission.ACCESS_COARSE_LOCATION;
if(EasyPermissions.hasPermissions(this, locationPermission)) {
Logger.i("已有权限");
}else {
Logger.i("请求权限");
EasyPermissions.requestPermissions(this, "我需要这个权限来侵犯隐私", 100, locationPermission);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
Logger.i("被android接到权限允许回调");
}

如果只是执行以上方法, 结果请求成功后只会回调onRequestPermissionsResult()方法, 这是activity自带的方法.

统一权限申请回调

如果想让EasyPermissions帮你统一管理你的权限执行流程需要实现以下方法

重写Activity的方法onRequestPermissionsResult

1
2
3
4
5
6
7
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// 以下方法将把权限结果执行给EasyPermission
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}

让Activity实现EasyPermissions.PermissionCallbacks接口

然后重写以下方法

1
2
3
4
5
6
7
8
9
@Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
Logger.i("允许权限");
}
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
Logger.i("拒绝权限");
}

这样用户拒绝或者允许都会回调EasyPermissions.PermissionCallbacks的两个方法

如果想在用户允许权限后执行自己的特定方法

可以在方法前面增加注释@AfterPermissionGranted(int requestCode), 该注释可以根据请求码来选择性执行.

再次唤醒权限申请

在用户第二次弹出相同权限允许弹窗时, 有不再询问的选项, 如果用户选择后如何再次唤醒呢?

即可通过以下方法判断该权限是否被不再询问

1
EasyPermissions.somePermissionPermanentlyDenied(...)

然后强制弹出

1
2
3
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
new AppSettingsDialog.Builder(this).build().show();
}