一、 敏感权限列表
详见:https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous
二、 权限适配框架接口说明
类名 | 方法名 | 方法说明 |
PermissionManager | hasPermission | 判断是否拥有某个权限 |
requestPermission | 申请某个权限 | |
requestAfterExplanation | 申请某个权限(向用户展示完权限说明弹框后调用) | |
cancelAfterExplanation | 取消某个权限申请(向用户展示完权限说明弹框后调用) | |
shouldShowRequestPermissionRationale | 是否需要展示权限说明(系统接口,如果用户永远拒绝了权限,则此方法返回false) | |
openAppDetailPage | 打开系统设置中的应用详情页,用于用户永久拒绝权限后的引导开启 | |
registerPermissionCallback | 注册权限监听接口 | |
unRegisterPermissionCallback | 反注册权限监听接口 | |
PermissionCallback | onPermissionGranted | 权限授权成功的回调 |
onPermissionRejected | 权限被拒绝的回调 | |
isExplanationNeeded | 权限是否需要展示说明弹框的回调 | |
onShowExplanation | 展示提示弹框的回调(重载这个方法,展示权限说明弹框) |
三、 权限适配步骤
旧的步骤:
新的步骤:
四、 适配示例
以连接模块中的使用二维码连接电脑功能为例,介绍权限适配方法。具体代码详见:
com.connector.tencent.connector.CaptureActivity |
1、 在initCamera方法中,判断是否拥有相机权限。如果有权限,直接走原来的逻辑,打开相机;如果没有权限,则启动线程,在线程中注册权限请求回调,请求权限。(为什么要放到线程中请求?因为权限请求会阻塞当前线程执行,如果在主线程请求会导致UI无响应)。
if (PermissionManager.get().hasPermission(android.Manifest.permission.CAMERA)) { CameraManager.get().openDriver(surfaceHolder); if (handler == null) { handler = new CaptureActivityHandler(this, decodeFormats, characterSet); } } else { TemporaryThreadManager.get().start(new Runnable() {
@Override public void run() { if (!isRequesting) { isRequesting = true; PermissionManager.get().registerPermissionCallback(mPermissionCallback); PermissionManager.get().requestPermission(android.Manifest.permission.CAMERA); } } }); } |
2、 实现PermissionCallback回调。isExplanationNeeded方法用户让调用方选择是否需要展示权限说明。一般情况下,第一次请求权限可以不展示说明,如果用户拒绝了权限,第二次请求时,可以先展示解释权限用途的弹框,如果用户同意请求,则调用requestAfterExplanation方法继续请求权限;如果用户拒绝请求权限,则调用cancelAfterExplanation方法,取消权限请求,调用此方法后,会回调onPermissionRejected方法。
private PermissionCallback mPermissionCallback = new PermissionCallback.Stub() { @Override public void onPermissionRejected(String permissionName) { showPermissionRejectedDialog(permissionName); }
@Override public void onPermissionGranted(String permissionName) { initCamera(surfaceView.getHolder()); isRequesting = false; }
@Override public boolean isExplanationNeeded(String[] permissions) { for (String permission : permissions) { if (android.Manifest.permission.CAMERA.equals(permission) && PermissionManager.get().shouldShowRequestPermissionRationale(permission)) { return true; } } return false; }
@Override public void onShowExplanation(String[] permissions) { for (String permission : permissions) { if (android.Manifest.permission.CAMERA.equals(permission)) { showNeedPermissionDialog(permission); } } } }; |
3、 shouldShowRequestPermissionRationale是Android官方提供的方法,用于判断是否需要展示权限说明。第一次请求权限时默认返回false,及不需要显示;第二次请求权限时调用此方法时,会返回true(因为第一次用户拒绝了,说明用户对权限用途不理解,所以必须解释权限用途了)。如果第二次申请权限,用户还是拒绝了,并且勾选了“不再提示”的复选框,则此方法会返回false(很简单,因为用户不希望应用再弹框申请权限了,只有引导用户去设置里面手动开启了)。