前言
日前,项目中需要对App动态申请权限的功能做一次统一封装处理。原因就是公司信管部门的人告知我们需要在申请权限前,进行对申请权限的进行一次弹框提示解释其申请该权限的目的、用途。
而我们项目中因为历史原因代码中申请权限的位置并不统一。因此需要改造申请权限的流程。
一、梳理功能流程
经过一番沟通,明确在申请权限前,添加弹框提示的功能。其流程如下:
二、代码实现弹框功能
在编写代码前有几个方法有必要提前了解以下:
2.1:申请权限:
// 申请权限的核心方法 参数没啥好说的应该都能看懂
ActivityCompat.requestPermissions(activity, permissionArr, requestCode);
2.2:检测权限
// 检测权限是否被申请过
// PackageManager.PERMISSION_GRANTED 表示该权限已被允许
ActivityCompat.checkSelfPermission(activity, permission);
2.3:解释权限申请原因
如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don’t ask again 选项,此方法将返回 false。如果设备规范禁止应用具有该权限,此方法也会返回 false。
// 其作用 就是:在用户第一次拒绝某个权限后,使用该方法 返回true
// google 给出的流程描述:用户第一次申请权限前,直接进行申请。
// 当用户拒绝后 再次申请时 应该显示申请该权限的目的和描述,解释给用户
shouldShowRequestPermissionRationale(@NonNull String permission)
2.4.1:第一步检测权限
/**
* 检测权限是否全部同意
*
* @param activity activity
* @param permissions permissions
* @return true 申请的权限全部允许
*/
@Override
public boolean checkPermissionAllGrant(Activity activity, String... permissions) {
if (activity == null || permissions == null || permissions.length == 0) {
Log.e(TAG, "input params is error!!!");
return false;
}
boolean isAllGrant = true;
for (String permission : permissions) {
int result = ActivityCompat.checkSelfPermission(activity, permission);
if (result != PackageManager.PERMISSION_GRANTED) {
isAllGrant = false;
break;
}
}
return isAllGrant;
}
2.4.2:第二步显示弹框,请求权限
/**
* 显示权限描述弹框
*
* @param activity activity
* @param des 解释权限描述文字
* @param requestCode requestCode
* @param permissions permissions
*/
private void showExplainPermissionDialog(final Activity activity, HashSet<PermissionDesBean> des,
int requestCode, final String... permissions) {
ExplainPermissionDialog permissionDialog = new ExplainPermissionDialog(activity);
permissionDialog.setContent(des);
permissionDialog.setCancelText("取消");
permissionDialog.setSureText("确定");
permissionDialog.setOnItemClickListener(new ExplainPermissionDialog.OnItemClickListener() {
@Override
public void OnSureClick() {
// 同意开始申请权限
grantRequest(activity, requestCode, permissions);
}
@Override
public void OnCancelClick() {
// 拒绝开始申请权限
deniedRequest(activity);
}
});
permissionDialog.show();
}
/**
* 同意 开始申请权限
*
* @param activity activity
* @param requestCode requestCode
* @param permissions permissions
*/
private void grantRequest(Activity activity, int requestCode, String... permissions) {
ActivityCompat.requestPermissions(activity, permissions, requestCode);
}
/**
* 拒绝 开始申请权限
*/
private void deniedRequest(Context context) {
Toast.makeText(context, "权限开始申请已取消", Toast.LENGTH_SHORT).show();
}
2.4.3:处理权限申请结果
@Override
public void handlerRequestPermissionResult(Activity activity, String[] permissions, int[] grantResults,
PermissionRequestResultCall call) {
boolean result = checkRequestPermissionResult(grantResults);
if (result) {
if (call != null) {
// 权限全部同意
call.onAllGranted();
}
} else {
if (call != null) {
// 权限有被拒绝
call.onDenied();
}
String permissionName = getDeniedPermissionDes(activity, permissions, grantResults);
showSettingPermissionDialog(activity, permissionName);
}
}
/**
* 检查权限请求结果
*
* @return true 申请的权限全部允许
*/
private boolean checkRequestPermissionResult(int[] grantResults) {
boolean allGrant = true;
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
allGrant = false;
break;
}
}
return allGrant;
}
2.4.4:显示去设置弹框
/**
* 显示去设置弹框
*
* @param activity activity
*/
private void showSettingPermissionDialog(final Activity activity, String permissionName) {
String des = "新东方app需要" + permissionName + "为您提供相关功能,请在设置中开启";
SettingPermissionDialog permissionDialog = new SettingPermissionDialog(activity);
permissionDialog.setContent(des);
permissionDialog.setCancelText("取消");
permissionDialog.setSureText("去设置");
permissionDialog.setSureTextColor(activity.getResources().getColor(R.color.permission_color_E63750DD));
permissionDialog.setOnItemClickListener(new SettingPermissionDialog.OnItemClickListener() {
@Override
public void OnSureClick() {
// 去设置
grantToSetting(activity);
}
@Override
public void OnCancelClick() {
// 取消申请权限
cancelRequest(activity);
}
});
permissionDialog.show();
}
三、使用
3.1:请求权限
// 相机
String camera = Manifest.permission.CAMERA;
// 存储
String storage = Manifest.permission.WRITE_EXTERNAL_STORAGE;
// 麦克风
String audio = Manifest.permission.RECORD_AUDIO;
boolean isGranted = PermissionRequestUtils.getInstance().checkPermissionAllGrant(this, camera, storage, audio);
if (!isGranted) {
PermissionRequestUtils.getInstance().requestPermission(this, 10001, camera, storage, audio);
}
3.2:处理权限申请结果
/**
* 申请结果
*
* @param requestCode requestCode
* @param permissions permissions
* @param grantResults grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
PermissionRequestUtils.getInstance().handlerRequestPermissionResult(this, permissions, grantResults, new PermissionRequestUtils.PermissionRequestResultCall() {
@Override
public void onAllGranted() {
// 全部同意
}
@Override
public void onDenied() {
// 未全部同意
}
});
}
}
完整代码
总结:
这次主要是再次梳理了android动态权限申请的相关步骤和流程。具体使用的时候还有根据对应的业务需求。