Skip to content

Commit 11d5a3c

Browse files
committed
优化框架的代码分类
优化和补充框架文档 新增支持申请闹钟权限 新增支持申请勿扰权限 新增支持申请通知栏监听权限 新增支持设置权限页跳转回调监听 修正权限错误检测类几处代码逻辑
1 parent 91f0fbd commit 11d5a3c

28 files changed

+1311
-720
lines changed

HelpDoc.md

Lines changed: 42 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
* [新版框架为什么移除了国产手机权限设置页功能](#新版框架为什么移除了国产手机权限设置页功能)
2222

23+
* [为什么不用 ActivityResultContract 来申请权限](为什么不用-activityresultcontract-来申请权限)
24+
2325
#### Android 11 定位权限适配
2426

2527
* 在 Android 10 上面,定位权限被划分为前台权限(精确和模糊)和后台权限,而到了 Android 11 上面,需要分别申请这两种权限,如果同时申请这两种权限会**惨遭系统无情拒绝**,连权限申请对话框都不会弹,立马被系统拒绝,直接导致定位权限申请失败。
@@ -111,107 +113,38 @@ XXPermissions.with(MainActivity.this)
111113

112114
#### 我想在申请前和申请后统一弹对话框该怎么处理
113115

114-
* 在 Application 初始化的时候配置
116+
* 框架内部有提供一个拦截器接口,通过实现框架中提供的 [IPermissionInterceptor](/library/src/main/java/com/hjq/permissions/IPermissionInterceptor.java) 接口即可,具体实现可参考 Demo 中提供的 [PermissionInterceptor](app/src/main/java/com/hjq/permissions/demo/PermissionInterceptor.java) 类,建议下载源码后进行阅读,再将代码引入到项目中
117+
118+
* 使用拦截的方式也很简单,具体有两种设置方式,一种针对局部设置,另外一种是全局设置
115119

116120
```java
117-
public class XxxApplication extends Application {
121+
XXPermissions.with(this)
122+
.permission(Permission.XXX)
123+
// 设置权限请求拦截器(局部设置)
124+
.interceptor(new PermissionInterceptor())
125+
.request(new OnPermissionCallback() {
118126

119-
@Override
120-
public void onCreate() {
121-
super.onCreate();
122-
// 设置权限申请拦截器
123-
XXPermissions.setInterceptor(new PermissionInterceptor());
124-
}
125-
}
126-
```
127+
@Override
128+
public void onGranted(List<String> permissions, boolean all) {
129+
......
130+
}
127131

128-
* PermissionInterceptor 源码实现
132+
@Override
133+
public void onDenied(List<String> permissions, boolean never) {
134+
......
135+
}
136+
});
137+
```
129138

130139
```java
131-
public final class PermissionInterceptor implements IPermissionInterceptor {
132-
133-
@Override
134-
public void requestPermissions(Activity activity, OnPermissionCallback callback, List<String> allPermissions) {
135-
// 这里的 Dialog 只是示例,没有用 DialogFragment 来处理 Dialog 生命周期
136-
new AlertDialog.Builder(activity)
137-
.setTitle("授权提示")
138-
.setMessage("使用此功能需要先授予权限")
139-
.setPositiveButton("授予", new DialogInterface.OnClickListener() {
140-
141-
@Override
142-
public void onClick(DialogInterface dialog, int which) {
143-
dialog.dismiss();
144-
PermissionFragment.beginRequest(activity, new ArrayList<>(allPermissions), PermissionInterceptor.this, callback);
145-
}
146-
})
147-
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
148-
149-
@Override
150-
public void onClick(DialogInterface dialog, int which) {
151-
dialog.dismiss();
152-
}
153-
})
154-
.show();
155-
}
156-
157-
@Override
158-
public void grantedPermissions(Activity activity, List<String> allPermissions, List<String> grantedPermissions,
159-
boolean all, OnPermissionCallback callback) {
160-
if (callback != null) {
161-
callback.onGranted(grantedPermissions, all);
162-
}
163-
}
140+
public class XxxApplication extends Application {
164141

165142
@Override
166-
public void deniedPermissions(Activity activity, List<String> allPermissions, List<String> deniedPermissions,
167-
boolean never, OnPermissionCallback callback) {
168-
if (callback != null) {
169-
callback.onDenied(deniedPermissions, never);
170-
}
171-
172-
if (never) {
173-
showPermissionDialog(activity, deniedPermissions);
174-
return;
175-
}
176-
177-
if (deniedPermissions.size() == 1 && Permission.ACCESS_BACKGROUND_LOCATION.equals(deniedPermissions.get(0))) {
178-
ToastUtils.show("没有授予后台定位权限,请您选择\"始终允许\"");
179-
return;
180-
}
181-
182-
ToastUtils.show("授权失败,请正确授予权限");
183-
184-
if (callback == null) {
185-
return;
186-
}
187-
callback.onDenied(deniedPermissions, never);
188-
}
189-
190-
/**
191-
* 显示授权对话框
192-
*/
193-
protected void showPermissionDialog(Activity activity, List<String> permissions) {
194-
// 这里的 Dialog 只是示例,没有用 DialogFragment 来处理 Dialog 生命周期
195-
new AlertDialog.Builder(activity)
196-
.setTitle("授权提醒")
197-
.setCancelable(false)
198-
.setMessage(getPermissionHint(activity, permissions))
199-
.setPositiveButton("前往授权", new DialogInterface.OnClickListener() {
200-
201-
@Override
202-
public void onClick(DialogInterface dialog, int which) {
203-
dialog.dismiss();
204-
XXPermissions.startPermissionActivity(activity, permissions);
205-
}
206-
})
207-
.show();
208-
}
209-
210-
/**
211-
* 根据权限获取提示
212-
*/
213-
protected String getPermissionHint(Context context, List<String> permissions) {
214-
// 具体实现请看 Demo 源码
143+
public void onCreate() {
144+
super.onCreate();
145+
146+
// 设置权限请求拦截器(全局设置)
147+
XXPermissions.setInterceptor(new PermissionInterceptor());
215148
}
216149
}
217150
```
@@ -253,11 +186,13 @@ XXPermissions.with(this)
253186

254187
#### 新版框架为什么移除了自动申请清单权限的功能
255188

189+
> [【issue】建议恢复跳转权限设置页和获取AndroidManifest的所有权限两个实用功能](https://github.com/getActivity/XXPermissions/issues/54)
190+
256191
* 获取清单权限并申请的功能,这个虽然非常方便,但是存在一些隐患,因为 apk 中的清单文件最终是由多个 module 的清单文件合并而成,会变得不可控,这样会使我们无法预估申请的权限,并且还会掺杂一些不需要的权限,所以经过慎重考虑移除该功能。
257192

258193
#### 新版框架为什么移除了不断申请权限的功能
259194

260-
* [【issue】建议恢复跳转权限设置页和获取AndroidManifest的所有权限两个实用功能](https://github.com/getActivity/XXPermissions/issues/54)
195+
> [【issue】关于拒绝权限后一直请求获取的优化问题](https://github.com/getActivity/XXPermissions/issues/39)
261196
262197
* 假设用户拒绝了权限,如果框架再次申请,那么用户会授予的可能性也是比较小,同时某些应用商店已经禁用了这种行为,经过慎重考虑,对这个功能相关的 API 进行移除。
263198

@@ -307,6 +242,12 @@ public class PermissionActivity extends AppCompatActivity implements OnPermissio
307242

308243
#### 新版框架为什么移除了国产手机权限设置页功能
309244

245+
> [【issue】权限拒绝并不再提示的问题](https://github.com/getActivity/XXPermissions/issues/99)
246+
247+
> [【issue】小米手机权限拒绝后,库中判断的小米权限设置界面开启无效](https://github.com/getActivity/XXPermissions/issues/38)
248+
249+
> [【issue】正常申请存储权限时,永久拒绝,然后再应用设置页开启权限询问,系统权限申请弹窗未显示](https://github.com/getActivity/XXPermissions/issues/100)
250+
310251
* XXPermissions 9.0 及之前是有存在这一功能的,但是我在后续的版本上面将这个功能移除了,原因是有很多人跟我反馈这个功能其实存在很大的缺陷,例如在一些华为新机型上面可能跳转的页面不是应用的权限设置页,而是所有应用的权限管理列表界面。
311252

312253
* 其实不止华为有问题,小米同样有问题,有很多人跟我反馈过同一个问题,XXPermissions 跳转到国产手机权限设置页,用户正常授予了权限之后返回仍然检测到权限仍然是拒绝的状态,这个问题反馈的次数很多,但是迟迟不能排查到原因,终于在最后一次得到答案了,[有人](https://github.com/getActivity/XXPermissions/issues/38)帮我排查到是 miui 优化开关的问题(小米手机 ---> 开发者选项 ---> 启用 miui 优化),那么问题来了,这个开关有什么作用?是如何影响到 XXPermissions 的?
@@ -329,4 +270,10 @@ public class PermissionActivity extends AppCompatActivity implements OnPermissio
329270

330271
* 另外值得一提的是 [Android 11 对软件包可见性进行了限制](https://developer.android.google.cn/about/versions/11/privacy/package-visibility),所以这种跳包名的方式在未来将会完全不可行。
331272

332-
* 最终决定:这个功能的出发点是好的,但是我们没办法做好它,经过慎重考虑,决定将这个功能在 XXPermissions 9.2 版本及之后的版本进行移除。
273+
* 最终决定:这个功能的出发点是好的,但是我们没办法做好它,经过慎重考虑,决定将这个功能在 [XXPermissions 9.2 版本](https://github.com/getActivity/XXPermissions/releases/tag/9.2)及之后的版本进行移除。
274+
275+
#### 为什么不用 ActivityResultContract 来申请权限
276+
277+
> [【issue】是否有考虑 onActivityResult 回调的权限申请切换成 ActivityResultContract](https://github.com/getActivity/XXPermissions/issues/103)
278+
279+
* ActivityResultContract 是 Activity `1.2.0-alpha02` 和 Fragment `1.3.0-alpha02` 中新追加的新 API,有一定的使用门槛,必须要求项目是基于 AndroidX,并且 AndroidX 的版本还要是 `1.3.0-alpha01` 以上才可以,如果替换成 `ActivityResultContract` 来实现,那么就会导致一部分开发者用不了 XXPermissions,这是一个比较严重的问题,但实际上换成 ActivityResultContract 来实现本身没有带来任何的效益,例如我之前解决过的 Fragment 屏幕旋转及后台申请的问题,所以更换的意义又在哪里呢?有人可能会说官方已经将 onActivityResult 标记成过时,大家不必担心,之所以标记成过时只不过是谷歌为了推广新技术,但是可以明确说,官方是一定不会删掉这个 API 的,更准确来说是一定不敢,至于为什么?大家可以去看看 ActivityResultContract 是怎么实现的?它也是通过重写 Activity 的 `onActivityResult`、`onRequestPermissionsResult` 方法回调实现的,具体大家可以去看 `androidx.activity.ComponentActivity` 类中这两个方法的实现就会明白了,这里不再赘述。

0 commit comments

Comments
 (0)