特别说明
AndPermission2.0发布之前邀请了一些中国开发者参与测试,测试并兼容了大量的中国产手机。虽然如此,但是在很多手机上测试结果还是不尽如人意,但是这些手机只是很少的一部分了,AndPermission也提供了合适的方法来兼容这种情况。
国产手机的各种情况比较多,这里就不一一例举说明了,这里说明一些使用AndPermission时出现的疑问。
为了兼容一些特殊中国产手机,AndPermission请求权限的流程是这样的:
发起请求
│
调用SDK Api判断是否有权限
│
┌─────────────┴─────────────┐
有权限 没权限
│ │
│ 使用SDK Api请求权限
│ │
│ 用户授权或者拒绝
└─────────────┬─────────────┘
执行权限相关代码
┌───────┴───────┐
正常 异常
│ │
onGranted() onDenied()
┌──────┴──────┐ │
正常 异常───────┘
申请流程的释义
可以看出AndPermission的申请流程和标准的申请流程大相径庭,这样做主要是因为以下几点原因。
- 兼容Android5.0的系统判断是否有权限。
- 部分设备上使用SDK的Api判断是否有权限时,无论是否有权限都返回
true
。 - 部分设备上无论用户点击同意还是拒绝都返回
true
。 - 部分设备在申请权限时并不会弹出授权
Dialog
,而是在执行权限相关代码时才会弹出授权Dialog
。
特特特别注意:因为部分权限(例如发送短信、打电话、接听/挂断电话等),AndPermission不能执行权限相关代码做测试,所以对于这一类权限在执行权限相关代码步骤仅仅使用了AppOpsManager做检测。因为极少部分国产机总是返回true
,因此直接回调到onGranted()
中让开发者执行相关代码来辅助AndPermission的整个流程,如果onGranted()
方法发生异常,那么则认为是没有权限,所以重新回调到onDenied()
方法中,如果onGranted()
方法正常执行那么则认为有权限。这样一来刚好是一个完整的流程,也可以最大限度的兼容到更多异常的手机。
回调onGranted()
时AndPermission对onGranted()
方法做了try catch
。这样做可以保证两点,第一点是防止部分手机返回错误状态时回调了onGranted()
后的崩溃,第二点是防止部分手机需要真正执行权限相关代码时触发授权Dialog
后被用户拒绝后的崩溃。而这两点都是没有权限,因此会重新回调到onDenied()
中让开发者处理没权限的情况。
综上所述,如果onGranted()
和onDenied()
方法都被调用了,说明开发者的onGranted()
方法发生了异常。
一些特例权限
- 身体传感器是在Wear OS使用的,绝大部分手机设备没有该权限的管理项,因此都返回
false
。在有该权限管理的手机设备中一直返回true,在手表上测试身体传感器权限时不存在问题。 - 获取手机账户、读取短信和定位权限在部分手机上永远不会弹出授权
Dialog
,并且实际没有权限时检测结果是有权限,执行权限相关代码做测试时也不会抛出异常,但是获取到的结果是null或者0。因此AndPermission会回调onGranted()
,开发者可以在获取到结果是null时,可以提示用户获取信息失败或者检查权限等。 - 大多数国产设备的电话权限组中的
PROCESS_OUTGOING_CALLS
权限只会授权给系统App使用,就算用户点击了同意也不会授权给普通App,除非用户在系统的设置中手动开启该权限。因此当开发者申请电话权限组时,在用户点击同意后AndPermission还是可能回调onDened()
方法(这取决于App是否真正的有该权限),因此对于电话权限组,使用什么权限就申请什么权限,不要申请权限组。
总结
有一个原则是使用什么权限就申请什么权限,不要过多的申请权限。比如电话、短信和联系人这种隐私级别比较高的要特别注意;比如日历、相机、定位、麦克风和存储设备这些常用且隐私级别不高的权限可以请求权限组,这些权限经过测试存在的问题也比较少。