1.简介
在Android6.0之前版本,权限请求较为简单,仅在用户安装app时将自己需要使用的所有权限列出来告知用户,若用户授权,则app安装后可随时使用该权限。自6.0开始,一些涉及用户隐私的敏感权限需在使用时动态申请,且用户可选择授权或拒绝。当然,权限的改进对用户而言是好事,毕竟更能保护用户隐私。但对于开发者而言,也多了一项动态权限申请的工作
2.权限分类
对开发者而言,权限则主要分为以下两类:
1)普通权限(normal permissions): 只需在manifest中注册
2)危险权限(dangerous permissions):除需在manifest中注册外,还需动态申请
危险权限如下:
3.运行时权限申请(使用系统提供的API)
1)权限检查
int result = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
if (result == PackageManager.PERMISSION_GRANTED) {
//请求的权限权限被授予
}else {
//请求的权限被拒绝
}
2)请求权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
requestCode);
注意:Fragment中请求需使用自己的requestPermissions方法
3)处理请求结果
请求权限后系统会回调申请权限的Activity的onRequestPermissionsResult(),若使用的是Fragment的requestPermissions方法,则回调对应Fragment的onRequestPermissionsResult()
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode != this.requestCode) {
return;
}
for (int i = 0; i < grantResults.length; i++) {
String permission = permissions[i];
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, permission + "已被授权", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, permission + "已被拒绝", Toast.LENGTH_SHORT).show();
if (shouldShowRequestPermissionRationale(permission)) {
//请求被用户拒绝但用户未勾选不再询问框,可继续请求权限
} else {
//请求被用户拒绝且用户勾选了不再询问框,需要用户前往设置中授权
}
}
}
}
4)总结
用系统提供的api进行申请步骤较为繁琐,且请求和处理代码不在相同位置,代码量多了的话可读性变差。那有没有什么好的方法可以简化流程并能提高可读性呢?答案是肯定的,著名基佬交流网站github上就有丰富的权限请求库供各位客官享用
4.使用EasyPermissions进行权限申请
1)EasyPermissions简介
github上有很多动态权限申请库,比如rxpermissions,该库最大的亮点是和rxjava配合使用,链式操作简单方便。但rxpermissions要求我们必须依赖rxjava,而有时我们可能并不想依赖rxjava,并且rxpermissions连续执行相同权限的请求可能会回调多次。因此,可使用EasyPermissions进行运行时权限申请,该库特点如下:
- 链式操作(这点和rxpermissions一样,不同的是无需依赖rxjava)
- 请求前会自动检查是否已被授予 (这样在请求前就不必再进行权限检查了)
- 请求间互不影响,即使每次请求的是相同权限
- 若请求的权限未在manifest中注册,将抛出明确的异常 (请求未在manifest注册的权限将导致不弹出dialog而直接返回false,有时我们可能对此十分懵逼,因为这既不报错也不弹出dialog代码也OK就是请求失败,可能要很久才反应过来忘了在manifest中注册)
地址:https://github.com/Ficat/EasyPermissions
2)依赖
A.在根build.gradle中添加
allprojects {
repositories {
maven { url 'https://jitpack.io' }
}
}
B.添加依赖
dependencies {
implementation 'com.github.Ficat:EasyPermissions:v1.0.1'
}
3)使用
A.创建easypermissions对象
EasyPermissions easyPermissions = new EasyPermissions(activity);
B.请求权限
//request方式,请求的所有权限被用户授权后返回true,否则返回false
easyPermissions.request(Manifest.permission.CAMERA,Manifest.permission.CALL_PHONE)
.subscribe(new RequestSubscriber<Boolean>() {
@Override
public void onPermissionsRequestResult(Boolean granted) {
if (granted) {
//摄像头、拨打电话都被用户授权
} else {
//摄像头、拨打电话任意一项被拒绝或两者都被拒绝
}
}
});
//requestEach方式
easyPermissions.requestEach(Manifest.permission.CAMERA,Manifest.permission.CALL_PHONE)
.subscribe(new RequestSubscriber<Permission>() {
@Override
public void onPermissionsRequestResult(Permission permission) {
//权限名
String name = permission.name;
if (permission.granted) {
//name权限被授予
} else {
if (permission.shouldShowRequestPermissionRationale) {
//name权限被拒绝但用户未勾选不再询问框
} else {
//name权限被拒绝且用户勾选了不再询问框
//此时就不能再次请求name权限了,而需user前往设置界面授权
}
}
}
});
网友评论