原文地址:https://blog.csdn.net/jianesrq0724/article/details/77100942
关于Android6.0运行时权限的介绍、如何检查权限、授予权限,请看另一篇文章。
可能大家会有疑问,上面的的文章,已经对运行时权限讲解的很详细了,为啥还会有这篇。之前的授权的思路是,用户必须要同意所有的授权后,才能进入首页 。通过友盟埋点分析,用户同意所有的权限后才进入App,这样会导致少部分用户流失。
于是引用了另一种思路,在欢迎页面进行部分授权,用户拒绝授权后,不再弹出授权对话框,直接进入首页。在进入首页后,遇到需要授权的地方,再单独授权;当用户拒绝后,自定义一个弹窗,提示用户手动去开启权限。通过这样的方法,极大的提升了用户的体验度
在进行代码分析前,唠叨几句,可能有人会有疑问。进入首页,需要权限的地方会单独授权,为啥还要在欢迎界面授权判断。这样做的好处有两点:1、每次启动App都需定位,并上传位置 2、读写内存卡这个权限很多地方需要,最好在启动的时候就申请。
1、检查权限哪些权限未授予,用List集合保存未授予的权限,当List集合不为空的时候,请求授予权限的代码,当List集合为空,表示没有需要授予权限。
/**
* 检查权限
*/
private void checkPermission() {
mPermissionList.clear();
/**
* 判断哪些权限未授予
*/
for (int i = 0; i < permissions.length; i++) {
if (ContextCompat.checkSelfPermission(mContext, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
mPermissionList.add(permissions[i]);
}
}
/**
* 判断是否为空
*/
if (mPermissionList.isEmpty()) {//未授予的权限为空,表示都授予了
delayEntryPage();
} else {//请求权限方法
String[] permissions = mPermissionList.toArray(new String[mPermissionList.size()]);//将List转为数组
ActivityCompat.requestPermissions(WelcomeActivity.this, permissions, PERMISSION_REQUEST);
}
}
* 检查权限
*/
private void checkPermission() {
mPermissionList.clear();
/**
* 判断哪些权限未授予
*/
for (int i = 0; i < permissions.length; i++) {
if (ContextCompat.checkSelfPermission(mContext, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
mPermissionList.add(permissions[i]);
}
}
/**
* 判断是否为空
*/
if (mPermissionList.isEmpty()) {//未授予的权限为空,表示都授予了
delayEntryPage();
} else {//请求权限方法
String[] permissions = mPermissionList.toArray(new String[mPermissionList.size()]);//将List转为数组
ActivityCompat.requestPermissions(WelcomeActivity.this, permissions, PERMISSION_REQUEST);
}
}
2、响应权限的代码做了修改,不管用户拒绝还是同业,都进入首页
/**
* 响应授权
* 这里不管用户是否拒绝,都进入首页,不再重复申请权限
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PERMISSION_REQUEST:
delayEntryPage();
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
break;
}
}
* 响应授权
* 这里不管用户是否拒绝,都进入首页,不再重复申请权限
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PERMISSION_REQUEST:
delayEntryPage();
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
break;
}
}
3、下面 以打电话为例子,执行的步骤,首先检查权限电话权限。
/**
* 检查电话权限
*/
private void checkCallPhonePermission() {
if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions((Activity) mContext, new String[]{Manifest.permission.CALL_PHONE}, CALL_PHONE_PERMISSION);
} else {
showCallPhone();
}
}
*/
private void checkCallPhonePermission() {
if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions((Activity) mContext, new String[]{Manifest.permission.CALL_PHONE}, CALL_PHONE_PERMISSION);
} else {
showCallPhone();
}
}
- 已授予,弹出是拨打电话确认框
- 未授予,进行权限申请
请求权限,弹出权限申请对话框,会出现两种情况:
- 1、用户允许权限,直接弹出拨打电话确认框
- 2、用户拒绝权限,自定义一个弹窗,提示用户手动去开启权限 ,用户点击确认的时候,进入应用设置界面
/**
* 响应权限
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (grantResults == null || grantResults.length == 0) {//部分手机上,可能会出现grantResult length为0的情况
showPermission();
return;
}
switch (requestCode) {
case CALL_PHONE_PERMISSION:
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
showPermission();
return;
}
showCallPhone();
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
break;
}
}
* 响应权限
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (grantResults == null || grantResults.length == 0) {//部分手机上,可能会出现grantResult length为0的情况
showPermission();
return;
}
switch (requestCode) {
case CALL_PHONE_PERMISSION:
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
showPermission();
return;
}
showCallPhone();
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
break;
}
}
注:这里进行补充说明,为啥要判断grantResults为null和长度为0的情况,在部分手机上,当用户拒绝权限的时候,grantResults的长度为0,grantResults[0]会出现数据越界崩溃。
崩溃的机型:CAM-AL00、CAM-TL00、CAM-TL00H、KIW-TL00、HUAWEI RIO-AL00、HUAWEI RIO-TL00、KIW-TL00H、NEM-TL00等,这里只列举部分。
完整的代码,可以去GitHub上看,GitHub地址