Skip to content

Commit 1683080

Browse files
committed
修复在部分 Android 11 手机上无法同时申请前后台定位权限的问题
优化权限请求拦截器的处理逻辑及后台定位权限永久拒绝的判断逻辑
1 parent d1c5ef2 commit 1683080

File tree

7 files changed

+96
-29
lines changed

7 files changed

+96
-29
lines changed

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@
1919

2020
```groovy
2121
buildscript {
22-
......
22+
repositories {
23+
maven { url 'https://jitpack.io' }
24+
}
2325
}
2426
allprojects {
2527
repositories {
26-
// JitPack 远程仓库:https://jitpack.io
2728
maven { url 'https://jitpack.io' }
2829
}
2930
}
@@ -42,7 +43,7 @@ android {
4243
4344
dependencies {
4445
// 权限请求框架:https://github.com/getActivity/XXPermissions
45-
implementation 'com.github.getActivity:XXPermissions:10.8'
46+
implementation 'com.github.getActivity:XXPermissions:11.0'
4647
}
4748
```
4849

@@ -150,8 +151,8 @@ public class XxxActivity extends AppCompatActivity {
150151

151152
| 功能及细节 | [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) | [AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode) |
152153
| :--------: | :------------: | :------------: | :------------: | :------------: | :------------: | :------------: | :------------: |
153-
| 对应版本 | 10.8 | 2.0.3 | 0.12 | 4.8.0 | 3.0.0 | 1.4.0 | 1.30.5 |
154-
| 框架体积 | [24 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) | [91 KB](https://bintray.com/hotchemi/org.permissionsdispatcher/permissionsdispatcher-processor#files/org/permissionsdispatcher/permissionsdispatcher-processor) | [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) | [483 KB](https://bintray.com/blankj/maven/UtilCode#files/com/blankj/utilcode) |
154+
| 对应版本 | 11.0 | 2.0.3 | 0.12 | 4.8.0 | 3.0.0 | 1.4.0 | 1.30.5 |
155+
| 框架体积 | [27 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) | [91 KB](https://bintray.com/hotchemi/org.permissionsdispatcher/permissionsdispatcher-processor#files/org/permissionsdispatcher/permissionsdispatcher-processor) | [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) | [483 KB](https://bintray.com/blankj/maven/UtilCode#files/com/blankj/utilcode) |
155156
| 安装包权限 ||||||||
156157
| 悬浮窗权限 ||||||||
157158
| 通知栏权限 ||||||||

XXPermissions.apk

-140 KB
Binary file not shown.

app/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ android {
77
applicationId "com.hjq.permissions.demo"
88
minSdkVersion 14
99
targetSdkVersion 30
10-
versionCode 1080
11-
versionName "10.8"
10+
versionCode 1100
11+
versionName "11.0"
1212
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
1313
}
1414

@@ -43,7 +43,7 @@ dependencies {
4343
implementation 'com.android.support:appcompat-v7:28.0.0'
4444

4545
// 吐司框架:https://github.com/getActivity/ToastUtils
46-
implementation 'com.github.getActivity:ToastUtils:9.0'
46+
implementation 'com.github.getActivity:ToastUtils:9.2'
4747

4848
// 内存泄漏检测:https://github.com/square/leakcanary
4949
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'

library/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ android {
55

66
defaultConfig {
77
minSdkVersion 11
8-
versionCode 1080
9-
versionName "10.8"
8+
versionCode 1100
9+
versionName "11.0"
1010
}
1111

1212
// 使用 JDK 1.8

library/src/main/java/com/hjq/permissions/PermissionChecker.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ static void checkStoragePermission(Context context, List<String> requestPermissi
115115

116116
int cookie = PermissionUtils.findApkPathCookie(context);
117117
if (cookie == 0) {
118+
// 如果 cookie 为 0,证明获取失败,直接 return
118119
return;
119120
}
120121

library/src/main/java/com/hjq/permissions/PermissionFragment.java

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,20 @@ public final class PermissionFragment extends Fragment implements Runnable {
2929
/** 请求码(自动生成)*/
3030
private static final String REQUEST_CODE = "request_code";
3131

32+
/** 是否经过拦截器 */
33+
private static final String USE_INTERCEPTOR = "use_interceptor";
34+
3235
/** 权限请求码存放集合 */
3336
private final static SparseBooleanArray REQUEST_CODE_ARRAY = new SparseBooleanArray();
3437

38+
public static void beginRequest(FragmentActivity activity, ArrayList<String> permissions, OnPermissionCallback callback) {
39+
beginRequest(activity, permissions, true, callback);
40+
}
41+
3542
/**
3643
* 开启权限申请
3744
*/
38-
public static void beginRequest(FragmentActivity activity, ArrayList<String> permissions, OnPermissionCallback callback) {
45+
private static void beginRequest(FragmentActivity activity, ArrayList<String> permissions, boolean interceptor, OnPermissionCallback callback) {
3946
PermissionFragment fragment = new PermissionFragment();
4047
Bundle bundle = new Bundle();
4148
int requestCode;
@@ -47,6 +54,7 @@ public static void beginRequest(FragmentActivity activity, ArrayList<String> per
4754
REQUEST_CODE_ARRAY.put(requestCode, true);
4855
bundle.putInt(REQUEST_CODE, requestCode);
4956
bundle.putStringArrayList(REQUEST_PERMISSIONS, permissions);
57+
bundle.putBoolean(USE_INTERCEPTOR, interceptor);
5058
fragment.setArguments(bundle);
5159
// 设置保留实例,不会因为屏幕方向或配置变化而重新创建
5260
fragment.setRetainInstance(true);
@@ -216,6 +224,8 @@ public void requestDangerousPermission() {
216224
return;
217225
}
218226

227+
final int requestCode = arguments.getInt(REQUEST_CODE);
228+
219229
final ArrayList<String> allPermissions = arguments.getStringArrayList(REQUEST_PERMISSIONS);
220230
if (allPermissions == null || allPermissions.size() == 0) {
221231
return;
@@ -243,30 +253,58 @@ public void requestDangerousPermission() {
243253
}
244254

245255
// 在 Android 10 的机型上,需要先申请前台定位权限,再申请后台定位权限
246-
PermissionFragment.beginRequest(activity, locationPermission, new OnPermissionCallback() {
256+
PermissionFragment.beginRequest(activity, locationPermission, false, new OnPermissionCallback() {
247257

248258
@Override
249259
public void onGranted(List<String> permissions, boolean all) {
250260
if (!all || !isAdded()) {
251261
return;
252262
}
253-
requestPermissions(allPermissions.toArray(new String[allPermissions.size() - 1]), arguments.getInt(REQUEST_CODE));
263+
264+
// 前台定位权限授予了,现在申请后台定位权限
265+
PermissionFragment.beginRequest(activity,
266+
PermissionUtils.asArrayList(Permission.ACCESS_BACKGROUND_LOCATION),
267+
false, new OnPermissionCallback() {
268+
269+
@Override
270+
public void onGranted(List<String> permissions, boolean all) {
271+
if (!all || !isAdded()) {
272+
return;
273+
}
274+
275+
// 前台定位权限和后台定位权限都授予了
276+
int[] grantResults = new int[allPermissions.size()];
277+
Arrays.fill(grantResults, PackageManager.PERMISSION_GRANTED);
278+
onRequestPermissionsResult(requestCode, allPermissions.toArray(new String[0]), grantResults);
279+
}
280+
281+
@Override
282+
public void onDenied(List<String> permissions, boolean never) {
283+
if (!isAdded()) {
284+
return;
285+
}
286+
287+
// 后台定位授权失败,但是前台定位权限已经授予了
288+
int[] grantResults = new int[allPermissions.size()];
289+
for (int i = 0; i < allPermissions.size(); i++) {
290+
grantResults[i] = Permission.ACCESS_BACKGROUND_LOCATION.equals(allPermissions.get(i)) ?
291+
PackageManager.PERMISSION_DENIED : PackageManager.PERMISSION_GRANTED;
292+
}
293+
onRequestPermissionsResult(requestCode, allPermissions.toArray(new String[0]), grantResults);
294+
}
295+
});
254296
}
255297

256298
@Override
257299
public void onDenied(List<String> permissions, boolean never) {
258300
if (!isAdded()) {
259301
return;
260302
}
261-
// 如果申请的权限里面只包含定位相关的权限,那么就直接回调失败
262-
if (permissions.size() == allPermissions.size() - 1) {
263-
int[] grantResults = new int[allPermissions.size()];
264-
Arrays.fill(grantResults, PackageManager.PERMISSION_DENIED);
265-
onRequestPermissionsResult(arguments.getInt(REQUEST_CODE), allPermissions.toArray(new String[0]), grantResults);
266-
return;
267-
}
268-
// 如果还有其他类型的权限组就继续申请
269-
requestPermissions(allPermissions.toArray(new String[allPermissions.size() - 1]), arguments.getInt(REQUEST_CODE));
303+
304+
// 前台定位授权失败,并且无法申请后台定位权限
305+
int[] grantResults = new int[allPermissions.size()];
306+
Arrays.fill(grantResults, PackageManager.PERMISSION_DENIED);
307+
onRequestPermissionsResult(requestCode, allPermissions.toArray(new String[0]), grantResults);
270308
}
271309
});
272310
}
@@ -279,7 +317,9 @@ public void onRequestPermissionsResult(int requestCode, String[] permissions, in
279317
return;
280318
}
281319

282-
OnPermissionCallback callBack = mCallBack;
320+
boolean useInterceptor = arguments.getBoolean(USE_INTERCEPTOR);
321+
322+
OnPermissionCallback callback = mCallBack;
283323
mCallBack = null;
284324

285325
for (int i = 0; i < permissions.length; i++) {
@@ -338,20 +378,32 @@ public void onRequestPermissionsResult(int requestCode, String[] permissions, in
338378

339379
// 如果请求成功的权限集合大小和请求的数组一样大时证明权限已经全部授予
340380
if (grantedPermission.size() == permissions.length) {
341-
// 代表申请的所有的权限都授予了
342-
XXPermissions.getInterceptor().grantedPermissions(activity, callBack, grantedPermission, true);
381+
if (useInterceptor) {
382+
// 代表申请的所有的权限都授予了
383+
XXPermissions.getInterceptor().grantedPermissions(activity, callback, grantedPermission, true);
384+
} else {
385+
callback.onGranted(grantedPermission, true);
386+
}
343387
return;
344388
}
345389

346390
// 获取被拒绝的权限
347391
List<String> deniedPermission = PermissionUtils.getDeniedPermissions(permissions, grantResults);
348392

349-
// 代表申请的权限中有不同意授予的,如果有某个权限被永久拒绝就返回 true 给开发人员,让开发者引导用户去设置界面开启权限
350-
XXPermissions.getInterceptor().deniedPermissions(activity, callBack, deniedPermission, PermissionUtils.isPermissionPermanentDenied(activity, deniedPermission));
393+
if (useInterceptor) {
394+
// 代表申请的权限中有不同意授予的,如果有某个权限被永久拒绝就返回 true 给开发人员,让开发者引导用户去设置界面开启权限
395+
XXPermissions.getInterceptor().deniedPermissions(activity, callback, deniedPermission, PermissionUtils.isPermissionPermanentDenied(activity, deniedPermission));
396+
} else {
397+
callback.onDenied(deniedPermission, PermissionUtils.isPermissionPermanentDenied(activity, deniedPermission));
398+
}
351399

352400
// 证明还有一部分权限被成功授予,回调成功接口
353401
if (!grantedPermission.isEmpty()) {
354-
XXPermissions.getInterceptor().grantedPermissions(activity, callBack, grantedPermission, false);
402+
if (useInterceptor) {
403+
XXPermissions.getInterceptor().grantedPermissions(activity, callback, grantedPermission, false);
404+
} else {
405+
callback.onDenied(grantedPermission, false);
406+
}
355407
}
356408
}
357409

library/src/main/java/com/hjq/permissions/PermissionUtils.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,14 +325,24 @@ static boolean isPermissionPermanentDenied(Activity activity, String permission)
325325
return false;
326326
}
327327

328+
// 重新检测后台定位权限是否永久拒绝
329+
if (isAndroid10()) {
330+
if (Permission.ACCESS_BACKGROUND_LOCATION.equals(permission) &&
331+
getPermissionStatus(activity, Permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_DENIED) {
332+
333+
return isPermissionPermanentDenied(activity, Permission.ACCESS_COARSE_LOCATION) ||
334+
isPermissionPermanentDenied(activity, Permission.ACCESS_FINE_LOCATION);
335+
}
336+
}
337+
328338
// 检测 10.0 的三个新权限
329339
if (!isAndroid10()) {
330340
if (Permission.ACCESS_BACKGROUND_LOCATION.equals(permission) ||
331341
Permission.ACCESS_MEDIA_LOCATION.equals(permission)) {
332342
return false;
333343
}
334344

335-
if (Permission.ACTIVITY_RECOGNITION.equals(permission) ) {
345+
if (Permission.ACTIVITY_RECOGNITION.equals(permission)) {
336346
return activity.checkSelfPermission(Permission.BODY_SENSORS) == PackageManager.PERMISSION_DENIED &&
337347
!activity.shouldShowRequestPermissionRationale(permission);
338348
}
@@ -460,6 +470,9 @@ static int findApkPathCookie(Context context) {
460470
e.printStackTrace();
461471
Method method = assets.getClass().getDeclaredMethod("getApkPaths");
462472
String[] apkPaths = (String[]) method.invoke(assets);
473+
if (apkPaths == null) {
474+
return cookie;
475+
}
463476
for (int i = 0; i < apkPaths.length; i++) {
464477
if (apkPaths[i].equals(path)) {
465478
cookie = i + 1;

0 commit comments

Comments
 (0)