Skip to content

Commit 02dca7a

Browse files
committed
修改适配分区存储的注册方式
修正添加权限常量时可能会出现重复添加的情况 修正添加权限常量时会引用外部 List 变量的问题
1 parent e5e3864 commit 02dca7a

File tree

11 files changed

+101
-61
lines changed

11 files changed

+101
-61
lines changed

HelpDoc.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,17 @@ public final class PermissionInterceptor implements IPermissionInterceptor {
169169
if (callback == null) {
170170
return;
171171
}
172-
// 回调授权成功的方法
173172
callback.onGranted(permissions, all);
174173
}
175174

176175
@Override
177176
public void deniedPermissions(Activity activity, OnPermissionCallback callback, List<String> permissions, boolean never) {
178177
if (never) {
179178
showPermissionDialog(activity, permissions);
179+
if (callback == null) {
180+
return;
181+
}
182+
callback.onDenied(permissions, never);
180183
return;
181184
}
182185

@@ -190,7 +193,6 @@ public final class PermissionInterceptor implements IPermissionInterceptor {
190193
if (callback == null) {
191194
return;
192195
}
193-
// 回调授权失败的方法
194196
callback.onDenied(permissions, never);
195197
}
196198

README.md

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ android {
4343
4444
dependencies {
4545
// 权限请求框架:https://github.com/getActivity/XXPermissions
46-
implementation 'com.github.getActivity:XXPermissions:12.2'
46+
implementation 'com.github.getActivity:XXPermissions:12.3'
4747
}
4848
```
4949

@@ -60,18 +60,21 @@ android.enableJetifier = true
6060

6161
#### 分区存储
6262

63-
* 如果项目已经适配了 Android 10 分区存储特性,请在 Application 初始化时加入
63+
* 如果项目已经适配了 Android 10 分区存储特性,请在 `AndroidManifest.xml` 中加入
6464

65-
```java
66-
public final class XxxApplication extends Application {
65+
```xml
66+
<manifest>
6767

68-
@Override
69-
public void onCreate() {
70-
super.onCreate();
71-
// 当前项目是否已经适配了分区存储的特性
72-
XXPermissions.setScopedStorage(true);
73-
}
74-
}
68+
<application>
69+
70+
<!-- 表示当前项目已经适配了分区存储特性 -->
71+
<meta-data
72+
android:name="ScopedStorage"
73+
android:value="true" />
74+
75+
</application>
76+
77+
</manifest>
7578
```
7679

7780
* 如果当前项目没有适配这特性,那么这一步骤可以忽略
@@ -135,6 +138,27 @@ public class XxxActivity extends AppCompatActivity {
135138
}
136139
```
137140

141+
#### 框架其他 API 介绍
142+
143+
```java
144+
// 判断一个或多个权限是否全部授予了
145+
XXPermissions.isGranted(Context context, String... permissions);
146+
147+
// 获取没有授予的权限
148+
XXPermissions.getDenied(Context context, String... permissions);
149+
150+
// 判断某个权限是否为特殊权限
151+
XXPermissions.isSpecial(String permission);
152+
153+
// 判断一个或多个权限是否被永久拒绝了
154+
XXPermissions.isPermanentDenied(Activity activity, String... permissions);
155+
156+
// 跳转到应用权限设置页
157+
XXPermissions.startPermissionActivity(Context context, String... permissions);
158+
XXPermissions.startPermissionActivity(Activity activity, String... permissions);
159+
XXPermissions.startPermissionActivity(Fragment fragment, String... permissions);
160+
```
161+
138162
#### 关于权限监听回调参数说明
139163

140164
* 我们都知道,如果用户全部授予只会调用 **onGranted** 方法,如果用户全部拒绝只会调用 **onDenied** 方法。
@@ -149,23 +173,23 @@ public class XxxActivity extends AppCompatActivity {
149173

150174
#### 不同权限请求框架之间的对比
151175

152-
| 功能及细节 | [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) |
176+
| 功能及细节 | [XXPermissions](https://github.com/getActivity/XXPermissions) | [AndPermission](https://github.com/yanzhenjie/AndPermission) | [PermissionX](https://github.com/guolindev/PermissionX) | [AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode) | [RxPermissions](https://github.com/tbruyelle/RxPermissions) | [PermissionsDispatcher](https://github.com/permissions-dispatcher/PermissionsDispatcher) | [EasyPermissions](https://github.com/googlesamples/easypermissions) |
153177
| :--------: | :------------: | :------------: | :------------: | :------------: | :------------: | :------------: | :------------: |
154-
| 对应版本 | 12.2 | 2.0.3 | 0.12 | 4.8.0 | 3.0.0 | 1.5.0 | 1.30.6 |
155-
| issues 数 | [![](https://img.shields.io/github/issues/getActivity/XXPermissions.svg)](https://github.com/getActivity/XXPermissions/issues) | [![](https://img.shields.io/github/issues/yanzhenjie/AndPermission.svg)](https://github.com/yanzhenjie/AndPermission/issues) | [![](https://img.shields.io/github/issues/tbruyelle/RxPermissions.svg)](https://github.com/tbruyelle/RxPermissions/issues) | [![](https://img.shields.io/github/issues/permissions-dispatcher/PermissionsDispatcher.svg)](https://github.com/permissions-dispatcher/PermissionsDispatcher/issues) | [![](https://img.shields.io/github/issues/googlesamples/easypermissions.svg)](https://github.com/googlesamples/easypermissions/issues) | [![](https://img.shields.io/github/issues/guolindev/PermissionX.svg)](https://github.com/guolindev/PermissionX/issues) | [![](https://img.shields.io/github/issues/Blankj/AndroidUtilCode.svg)](https://github.com/Blankj/AndroidUtilCode/issues) |
156-
| 框架体积 | 27 KB | 127 KB | 28 KB | 91 KB | 48 KB | 66 KB | 500 KB |
178+
| 对应版本 | 12.3 | 2.0.3 | 1.5.0 | 1.30.6 | 0.12 | 4.8.0 | 3.0.0 |
179+
| issues 数 | [![](https://img.shields.io/github/issues/getActivity/XXPermissions.svg)](https://github.com/getActivity/XXPermissions/issues) | [![](https://img.shields.io/github/issues/yanzhenjie/AndPermission.svg)](https://github.com/yanzhenjie/AndPermission/issues) | [![](https://img.shields.io/github/issues/guolindev/PermissionX.svg)](https://github.com/guolindev/PermissionX/issues) | [![](https://img.shields.io/github/issues/Blankj/AndroidUtilCode.svg)](https://github.com/Blankj/AndroidUtilCode/issues) | [![](https://img.shields.io/github/issues/tbruyelle/RxPermissions.svg)](https://github.com/tbruyelle/RxPermissions/issues) | [![](https://img.shields.io/github/issues/permissions-dispatcher/PermissionsDispatcher.svg)](https://github.com/permissions-dispatcher/PermissionsDispatcher/issues) | [![](https://img.shields.io/github/issues/googlesamples/easypermissions.svg)](https://github.com/googlesamples/easypermissions/issues) |
180+
| 框架体积 | 27 KB | 127 KB | 66 KB | 500 KB | 28 KB | 91 KB | 48 KB |
157181
| 安装包权限 ||||||||
158-
| 悬浮窗权限 ||| |||| |
182+
| 悬浮窗权限 ||| |||| |
159183
| 通知栏权限 ||||||||
160-
| 系统设置权限 ||| |||| |
161-
| Android 8.0 权限适配 ||| | ||||
162-
| Android 9.0 权限适配 |||| || ||
163-
| Android 10.0 权限适配 ||| | ||||
164-
| Android 11 新版存储权限 ||| | || ||
165-
| Android 11 新版定位策略 ||| | || ||
166-
| 屏幕方向旋转场景适配 |||| || ||
167-
| 后台申请权限场景适配 |||| ||||
168-
| 低级错误检测机制 |||| ||||
184+
| 系统设置权限 ||| |||| |
185+
| Android 8.0 权限适配 ||| | || | |
186+
| Android 9.0 权限适配 |||| || | |
187+
| Android 10.0 权限适配 ||| | || | |
188+
| Android 11 新版存储权限 ||| | || | |
189+
| Android 11 新版定位策略 ||| | || | |
190+
| 屏幕方向旋转场景适配 |||| || | |
191+
| 后台申请权限场景适配 |||||| | |
192+
| 低级错误检测机制 |||||| | |
169193

170194
#### 屏幕旋转场景适配介绍
171195

XXPermissions.apk

146 Bytes
Binary file not shown.

app/build.gradle

Lines changed: 2 additions & 2 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 1220
11-
versionName "12.2"
10+
versionCode 1230
11+
versionName "12.3"
1212
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
1313
}
1414

app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

1717
<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions" />
1818

19-
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" tools:node="replace" />
20-
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace" />
19+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
20+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2121
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
2222

2323
<uses-permission android:name="android.permission.RECORD_AUDIO" />

app/src/main/java/com/hjq/permissions/demo/AppApplication.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,5 @@ public void onCreate() {
2323

2424
// 设置权限申请拦截器
2525
XXPermissions.setInterceptor(new PermissionInterceptor());
26-
27-
// 告诉框架,当前项目已适配分区存储特性
28-
//XXPermissions.setScopedStorage(true);
2926
}
3027
}

app/src/main/java/com/hjq/permissions/demo/PermissionInterceptor.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,17 @@ public void grantedPermissions(Activity activity, OnPermissionCallback callback,
5353
if (callback == null) {
5454
return;
5555
}
56-
// 回调授权失败的方法
5756
callback.onGranted(permissions, all);
5857
}
5958

6059
@Override
6160
public void deniedPermissions(Activity activity, OnPermissionCallback callback, List<String> permissions, boolean never) {
6261
if (never) {
6362
showPermissionDialog(activity, permissions);
63+
if (callback == null) {
64+
return;
65+
}
66+
callback.onDenied(permissions, never);
6467
return;
6568
}
6669

@@ -74,7 +77,6 @@ public void deniedPermissions(Activity activity, OnPermissionCallback callback,
7477
if (callback == null) {
7578
return;
7679
}
77-
// 回调授权失败的方法
7880
callback.onDenied(permissions, never);
7981
}
8082

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 1220
9-
versionName "12.2"
8+
versionCode 1230
9+
versionName "12.3"
1010
}
1111

1212
// 使用 JDK 1.8

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,16 +102,18 @@ static boolean checkPermissionArgument(List<String> requestPermissions, boolean
102102
* 检查存储权限
103103
*
104104
* @param requestPermissions 请求的权限组
105-
* @param scopedStorage 是否适配了分区存储
106105
*/
107-
static void checkStoragePermission(Context context, List<String> requestPermissions, boolean scopedStorage) {
106+
static void checkStoragePermission(Context context, List<String> requestPermissions) {
108107
// 如果请求的权限中没有包含外部存储相关的权限,那么就直接返回
109108
if (!requestPermissions.contains(Permission.MANAGE_EXTERNAL_STORAGE) &&
110109
!requestPermissions.contains(Permission.READ_EXTERNAL_STORAGE) &&
111110
!requestPermissions.contains(Permission.WRITE_EXTERNAL_STORAGE)) {
112111
return;
113112
}
114113

114+
// 是否适配了分区存储
115+
boolean scopedStorage = PermissionUtils.isScopedStorage(context);
116+
115117
int cookie = PermissionUtils.findApkPathCookie(context);
116118
if (cookie == 0) {
117119
// 如果 cookie 为 0,证明获取失败,直接 return
@@ -136,14 +138,14 @@ static void checkStoragePermission(Context context, List<String> requestPermissi
136138
(requestPermissions.contains(Permission.MANAGE_EXTERNAL_STORAGE) || !scopedStorage)) {
137139
// 请在清单文件 Application 节点中注册 android:requestLegacyExternalStorage="true" 属性
138140
// 否则就算申请了权限,也无法在 Android 10 的设备上正常读写外部存储上的文件
139-
// 如果你的项目已经全面适配了分区存储,请调用 XXPermissions.setScopedStorage(true) 来跳过该检查
141+
// 如果你的项目已经全面适配了分区存储,请在清单文件中注册一个 meta-data 属性,<meta-data android:name="ScopedStorage" android:value="true" /> 来跳过该检查
140142
throw new IllegalStateException("Please register the android:requestLegacyExternalStorage=\"true\" attribute in the manifest file");
141143
}
142144

143145
// 如果在已经适配 Android 11 的情况下
144146
if (targetSdkVersion >= Build.VERSION_CODES.R &&
145147
!requestPermissions.contains(Permission.MANAGE_EXTERNAL_STORAGE) && !scopedStorage) {
146-
// 1. 适配分区存储的特性,并在 Application 初始化时调用 XXPermissions.setScopedStorage(true)
148+
// 1. 适配分区存储的特性,并在清单文件中注册一个 meta-data 属性,<meta-data android:name="ScopedStorage" android:value="true" />
147149
// 2. 如果不想适配分区存储,则需要使用 Permission.MANAGE_EXTERNAL_STORAGE 来申请权限
148150
// 上面两种方式需要二选一,否则无法在 Android 11 的设备上正常读写外部存储上的文件
149151
// 如果不知道该怎么选择,可以看文档:https://github.com/getActivity/XXPermissions/blob/master/HelpDoc

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import android.content.pm.PackageManager;
1010
import android.content.res.AssetManager;
1111
import android.os.Build;
12+
import android.os.Bundle;
1213
import android.os.Environment;
1314
import android.provider.Settings;
1415

@@ -516,4 +517,20 @@ static int findApkPathCookie(Context context) {
516517
}
517518
return cookie;
518519
}
520+
521+
/**
522+
* 判断是否适配了分区存储
523+
*/
524+
static boolean isScopedStorage(Context context) {
525+
try {
526+
String metaKey = "ScopedStorage";
527+
Bundle metaData = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA).metaData;
528+
if (metaData != null && metaData.containsKey(metaKey)) {
529+
return Boolean.parseBoolean(String.valueOf(metaData.get(metaKey)));
530+
}
531+
} catch (PackageManager.NameNotFoundException e) {
532+
e.printStackTrace();
533+
}
534+
return false;
535+
}
519536
}

0 commit comments

Comments
 (0)