|
6 | 6 |
|
7 | 7 | > 另外想对 Android 6.0 权限需要深入了解的,可以看这篇文章[Android 6.0 运行权限解析(高级篇)](https://www.jianshu.com/p/6a4dff744031) |
8 | 8 |
|
9 | | - |
| 9 | +   |
| 10 | +   |
10 | 11 |
|
11 | 12 | #### 集成步骤 |
12 | 13 |
|
13 | | - dependencies { |
14 | | - implementation 'com.hjq:xxpermissions:6.8' |
15 | | - } |
| 14 | +```groovy |
| 15 | +dependencies { |
| 16 | + implementation 'com.hjq:xxpermissions:8.2' |
| 17 | +} |
| 18 | +``` |
16 | 19 |
|
17 | 20 | #### 一句代码搞定权限请求,从未如此简单 |
18 | 21 |
|
19 | 22 | > [点此查看完整的示例代码](https://github.com/getActivity/XXPermissions/blob/master/app/src/main/java/com/hjq/permissions/demo/MainActivity.java) |
20 | 23 |
|
21 | | - XXPermissions.with(this) |
22 | | - // 可设置被拒绝后继续申请,直到用户授权或者永久拒绝 |
23 | | - //.constantRequest() |
24 | | - // 支持请求6.0悬浮窗权限8.0请求安装权限 |
25 | | - //.permission(Permission.SYSTEM_ALERT_WINDOW, Permission.REQUEST_INSTALL_PACKAGES) |
26 | | - // 不指定权限则自动获取清单中的危险权限 |
27 | | - .permission(Permission.Group.STORAGE, Permission.Group.CALENDAR) |
28 | | - .request(new OnPermission() { |
29 | | - |
30 | | - @Override |
31 | | - public void hasPermission(List<String> granted, boolean all) { |
32 | | - |
| 24 | +```java |
| 25 | +XXPermissions.with(this) |
| 26 | + // 可设置被拒绝后继续申请,直到用户授权或者永久拒绝 |
| 27 | + //.constantRequest() |
| 28 | + // 申请安装包权限 |
| 29 | + //.permission(Permission.REQUEST_INSTALL_PACKAGES) |
| 30 | + // 申请悬浮窗权限 |
| 31 | + //.permission(Permission.SYSTEM_ALERT_WINDOW) |
| 32 | + // 申请通知栏权限 |
| 33 | + //.permission(Permission.NOTIFICATION_SERVICE) |
| 34 | + // 申请系统设置权限 |
| 35 | + //.permission(Permission.WRITE_SETTINGS) |
| 36 | + // 申请单个权限 |
| 37 | + .permission(Permission.CAMERA) |
| 38 | + // 申请多个权限 |
| 39 | + .permission(Permission.Group.STORAGE) |
| 40 | + .request(new OnPermission() { |
| 41 | + |
| 42 | + @Override |
| 43 | + public void hasPermission(List<String> granted, boolean all) { |
| 44 | + if (all) { |
| 45 | + ToastUtils.show("获取存储和拍照权限成功"); |
| 46 | + } else { |
| 47 | + ToastUtils.show("获取权限成功,部分权限未正常授予"); |
33 | 48 | } |
34 | | - |
35 | | - @Override |
36 | | - public void noPermission(List<String> denied, boolean quick) { |
37 | | - |
| 49 | + } |
| 50 | + |
| 51 | + @Override |
| 52 | + public void noPermission(List<String> denied, boolean quick) { |
| 53 | + if (quick) { |
| 54 | + ToastUtils.show("被永久拒绝授权,请手动授予存储和拍照权限"); |
| 55 | + // 如果是被永久拒绝就跳转到应用权限系统设置页面 |
| 56 | + XXPermissions.startPermissionActivity(MainActivity.this, denied); |
| 57 | + } else { |
| 58 | + ToastUtils.show("获取存储和拍照权限失败"); |
38 | 59 | } |
39 | | - }); |
40 | | - |
41 | | -#### 是否有这个权限 |
42 | | - |
43 | | - if (XXPermissions.hasPermission(this, Permission.Group.STORAGE)) { |
44 | | - |
45 | | - } |
46 | | - |
47 | | -#### 跳转到设置页面 |
48 | | - |
49 | | - XXPermissions.startPermissionActivity(this); |
| 60 | + } |
| 61 | + }); |
| 62 | +``` |
50 | 63 |
|
51 | 64 | #### 框架亮点 |
52 | 65 |
|
|
66 | 79 |
|
67 | 80 | * 本框架不依赖 Support 库,兼容 Eclipse 和 Studio |
68 | 81 |
|
69 | | -#### 常见问题 |
| 82 | +#### Android 11 存储适配 |
| 83 | + |
| 84 | +* 如果你的项目需要适配 Android 11 存储权限,那么需要先将 targetSdkVersion 进行升级 |
| 85 | + |
| 86 | +```java |
| 87 | +android |
| 88 | + defaultConfig { |
| 89 | + targetSdkVersion 30 |
| 90 | + } |
| 91 | +} |
| 92 | +``` |
| 93 | + |
| 94 | +* 再添加 Android 11 存储权限注册到清单文件中 |
| 95 | + |
| 96 | +```xml |
| 97 | +<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> |
| 98 | +``` |
| 99 | + |
| 100 | +* 需要注意的是,旧版的存储权限也需要在清单文件中注册,因为在低于 Android 11 的环境下申请存储权限,框架会自动切换到旧版的申请方式 |
| 101 | + |
| 102 | +```xml |
| 103 | +<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> |
| 104 | +<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
| 105 | +``` |
| 106 | + |
| 107 | +* 最后直接调用下面这句代码 |
| 108 | + |
| 109 | +```java |
| 110 | +XXPermissions.with(MainActivity.this) |
| 111 | + // 不适配 Android 11 可以这样写 |
| 112 | + //.permission(Permission.Group.STORAGE) |
| 113 | + // 适配 Android 11 需要这样写,这里无需再写 Permission.Group.STORAGE |
| 114 | + .permission(Permission.MANAGE_EXTERNAL_STORAGE) |
| 115 | + .request(new OnPermission() { |
| 116 | + |
| 117 | + @Override |
| 118 | + public void hasPermission(List<String> granted, boolean all) { |
| 119 | + if (all) { |
| 120 | + ToastUtils.show("获取存储权限成功"); |
| 121 | + } |
| 122 | + } |
| 123 | + |
| 124 | + @Override |
| 125 | + public void noPermission(List<String> denied, boolean quick) { |
| 126 | + if (quick) { |
| 127 | + ToastUtils.show("被永久拒绝授权,请手动授予存储权限"); |
| 128 | + // 如果是被永久拒绝就跳转到应用权限系统设置页面 |
| 129 | + XXPermissions.startPermissionActivity(MainActivity.this, denied); |
| 130 | + } else { |
| 131 | + ToastUtils.show("获取存储权限失败"); |
| 132 | + } |
| 133 | + } |
| 134 | + }); |
| 135 | +``` |
| 136 | + |
| 137 | + |
| 138 | + |
| 139 | +#### 监听回调问题 |
70 | 140 |
|
71 | 141 | > 我们都知道,如果用户全部授予只会调用hasPermission方法,如果用户全部拒绝只会调用noPermission方法。 |
72 | 142 |
|
73 | 143 | > 但是还有一种情况,如果在请求多种权限的情况下,这些权限不是被全部授予或者全部拒绝了,而是部分授权部分拒绝这种情况,框架会如何处理回调呢? |
74 | 144 |
|
75 | 145 | > 框架会先调用noPermission方法,再调用hasPermission方法。其中我们可以通过hasPermission方法中的 all 参数来判断权限是否全部授予了。如果想知道回调中的某个权限是否被授权或者拒绝,可以调用List集合类中的contains(Permission.XXX)方法来判断这个集合中是否包含了这个权限。 |
76 | 146 |
|
| 147 | +#### 不同权限请求框架之间对比 |
| 148 | + |
| 149 | +| 功能及细节对比 | [XXPermissions](https://github.com/getActivity/XXPermissions) | [AndPermission](https://github.com/yanzhenjie/AndPermission) | [RxPermissions](https://github.com/tbruyelle/RxPermissions) | [PermissionsDispatcher](https://github.com/permissions-dispatcher/PermissionsDispatcher) | [EasyPermissions](https://github.com/googlesamples/easypermissions) | [PermissionX](https://github.com/guolindev/PermissionX) |
| 150 | +| :--------: | :------------: | :------------: | :------------: | :------------: | :------------: | :------------: | |
| 151 | +| aar 包大小 | [17 KB](https://bintray.com/getactivity/maven/xxpermissions#files/com/hjq/xxpermissions) | [127 KB](https://mvnrepository.com/artifact/com.yanzhenjie/permission) | [28 KB](https://jitpack.io/#com.github.tbruyelle/rxpermissions) | [22 KB](https://bintray.com/hotchemi/org.permissionsdispatcher/permissionsdispatcher#files/org/permissionsdispatcher/permissionsdispatcher) | [48 KB](https://bintray.com/easygoogle/EasyPermissions/easypermissions#files/pub/devrel/easypermissions) | [32 KB](https://bintray.com/guolindev/maven/permissionx#files/com/permissionx/guolindev/permissionx) | |
| 152 | +| minSdk 要求 | API 11+ | API 14+ | API 14+ | API 14+ | API 14+ | API 15+ | |
| 153 | +| targetSdk 要求 | API 23+ | API 29+ | API 29+ | API 29+ | API 30+ | API 30+ | |
| 154 | +| class 文件数量 | 8 个 | 110 个 | 3 个 | 37 个 | 15 个 | 16 个 | |
| 155 | +| 是否有依赖 | 无任何依赖 | 依赖 Support | 依赖 RxJava | 依赖 AndroidX | 依赖 AndroidX | 依赖 AndroidX | |
| 156 | +| 安装包权限 | 支持 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 | |
| 157 | +| 悬浮窗权限 | 支持 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 | |
| 158 | +| 通知栏权限 | 支持 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 | |
| 159 | +| 系统设置权限 | 支持 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 | |
| 160 | +| 国产手机权限设置界面 | 已适配 | 已适配 | 未适配 | 未适配 | 未适配 | 未适配 | |
| 161 | +| Android 11 存储权限 | 已适配 | 未适配 | 未适配 | 未适配 | 未适配 | 未适配 | |
| 162 | +| 判断权限被永久拒绝 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 | |
| 163 | +| 不断请求权限直到永久拒绝 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 | |
| 164 | + |
77 | 165 | #### 作者的其他开源项目 |
78 | 166 |
|
79 | 167 | * 架构工程:[AndroidProject](https://github.com/getActivity/AndroidProject) |
|
0 commit comments