Skip to content

Commit

Permalink
新增支持申请安卓 9.0 危险权限
Browse files Browse the repository at this point in the history
  • Loading branch information
getActivity committed Dec 10, 2020
1 parent 8caee34 commit f354124
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 56 deletions.
45 changes: 24 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
```groovy
dependencies {
// 权限请求框架:https://github.com/getActivity/XXPermissions
implementation 'com.hjq:xxpermissions:9.5'
implementation 'com.hjq:xxpermissions:9.6'
}
```

Expand All @@ -39,7 +39,7 @@ XXPermissions.with(this)
.request(new OnPermissionCallback() {

@Override
public void onGranted(List<String> granted, boolean all) {
public void onGranted(List<String> permissions, boolean all) {
if (all) {
toast("获取录音和日历权限成功");
} else {
Expand All @@ -48,11 +48,11 @@ XXPermissions.with(this)
}

@Override
public void onDenied(List<String> denied, boolean never) {
public void onDenied(List<String> permissions, boolean never) {
if (never) {
toast("被永久拒绝授权,请手动授予录音和日历权限");
// 如果是被永久拒绝就跳转到应用权限系统设置页面
XXPermissions.startPermissionActivity(MainActivity.this, denied);
XXPermissions.startPermissionActivity(MainActivity.this, permissions);
} else {
toast("获取录音和日历权限失败");
}
Expand Down Expand Up @@ -130,26 +130,26 @@ android
* 最后直接调用下面这句代码

```java
XXPermissions.with(MainActivity.this)
XXPermissions.with(this)
// 不适配 Android 11 可以这样写
//.permission(Permission.Group.STORAGE)
// 适配 Android 11 需要这样写,这里无需再写 Permission.Group.STORAGE
.permission(Permission.MANAGE_EXTERNAL_STORAGE)
.request(new OnPermissionCallback() {

@Override
public void onGranted(List<String> granted, boolean all) {
public void onGranted(List<String> permissions, boolean all) {
if (all) {
toast("获取存储权限成功");
}
}

@Override
public void onDenied(List<String> denied, boolean never) {
public void onDenied(List<String> permissions, boolean never) {
if (never) {
toast("被永久拒绝授权,请手动授予存储权限");
// 如果是被永久拒绝就跳转到应用权限系统设置页面
XXPermissions.startPermissionActivity(MainActivity.this, denied);
XXPermissions.startPermissionActivity(MainActivity.this, permissions);
} else {
toast("获取存储权限失败");
}
Expand All @@ -161,24 +161,27 @@ XXPermissions.with(MainActivity.this)

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

| 功能及细节对比 | [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)
| 功能及细节 | [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)
| :--------: | :------------: | :------------: | :------------: | :------------: | :------------: | :------------: |
| 对应版本 | 9.0 | 2.0.3 | 0.12 | 4.8.0 | 3.0.0 | 1.4.0 |
| 对应版本 | 9.6 | 2.0.3 | 0.12 | 4.8.0 | 3.0.0 | 1.4.0 |
| minSdk 要求 | API 11+ | API 14+ | API 14+ | API 14+ | API 14+ | API 15+ |
| class 文件数量 | 7 个 | 110 个 | 3 个 | 37 个 | 15 个 | 16 个 |
| aar 包大小 | [21 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) |
| 安装包权限 | 支持 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 |
| 悬浮窗权限 | 支持 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 |
| 通知栏权限 | 支持 | 出现崩溃 | 不支持 | 不支持 | 不支持 | 不支持 |
| 系统设置权限 | 支持 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 |
| Android 8.0 两个新危险权限 | 已适配 | 已适配 | 未适配 | 已适配 | 未适配 | 已适配 |
| Android 10.0 三个新危险权限 | 已适配 | 部分适配 | 未适配 | 已适配 | 未适配 | 已适配 |
| Android 11 新版存储权限 | 已适配 | 未适配 | 未适配 | 未适配 | 未适配 | 未适配 |
| Android 11 新版定位策略 | 已适配 | 未适配 | 未适配 | 未适配 | 未适配 | 未适配 |
| aar 包大小 | [19 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) |
| 安装包权限 |||||||
| 悬浮窗权限 |||||||
| 通知栏权限 |||||||
| 系统设置权限 |||||||
| Android 8.0 权限适配 |||||||
| Android 9.0 权限适配 |||||||
| Android 10.0 权限适配 |||||||
| Android 11 新版存储权限 |||||||
| Android 11 新版定位策略 |||||||

#### 框架亮点

* 首款适配 Android 11 的权限请求框架,适配过程几乎零成本
* 首款也是唯一一款适配 Android 11 的权限请求框架

* 首款也是唯一一款适配所有安卓版本的权限请求框架

* 简洁易用,采用链式调用的方式,使用只需一句代码

Expand All @@ -190,7 +193,7 @@ XXPermissions.with(MainActivity.this)

* 向下兼容属性,新权限在旧系统可以正常申请,无需调用者适配

* 本框架不依赖任何第三方库,整个框架大小只有 21 kb(是同类框架中体积最小的)
* 本框架不依赖任何第三方库,整个框架大小只有 19 kb(是同类框架中体积最小的)

* 如果申请的权限没有在清单文件中注册会抛出异常(仅在 Debug 模式下判断)

Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ android {
applicationId "com.hjq.permissions.demo"
minSdkVersion 14
targetSdkVersion 30
versionCode 95
versionName "9.5"
versionCode 96
versionName "9.6"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
Expand Down
9 changes: 2 additions & 7 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,18 @@

buildscript {
repositories {
maven { url 'http://maven.aliyun.com/nexus/content/repositories/gradle-plugin' }
maven { url 'https://jitpack.io' }
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.3'
classpath 'com.novoda:bintray-release:0.8.0'
classpath 'com.android.tools.build:gradle:3.4.0'
classpath 'com.novoda:bintray-release:0.9.2'
}
}

allprojects {
repositories {
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' }
maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter' }
maven { url 'https://maven.aliyun.com/nexus/content/repositories/central/' }
maven { url 'https://dl.bintray.com/getactivity/maven/' }
maven { url 'https://dl.bintray.com/umsdk/release' }
maven { url 'https://maven.google.com' }
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
8 changes: 4 additions & 4 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ android {
minSdkVersion 11
// noinspection ExpiredTargetSdkVersion
targetSdkVersion 23
versionCode 95
versionName "9.5"
versionCode 96
versionName "9.6"
}

lintOptions {
Expand All @@ -26,8 +26,8 @@ publish {
userOrg = 'getactivity'
groupId = 'com.hjq'
artifactId = 'xxpermissions'
version = '9.5'
description = 'Android 6.0 permissions adaptation framework'
publishVersion = '9.6'
desc = 'Android 6.0 permissions adaptation framework'
website = "https://github.com/getActivity/XXPermissions"
}

Expand Down
4 changes: 2 additions & 2 deletions library/src/main/java/com/hjq/permissions/Permission.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ private Permission() {}
/** 接收彩信 */
public static final String RECEIVE_MMS = "android.permission.RECEIVE_MMS";

///** 允许呼叫应用继续在另一个应用中启动的呼叫(需要 Android 9.0 及以上,极其少见,所以不做适配) */
//public static final String ACCEPT_HANDOVER = "android.permission.ACCEPT_HANDOVER";
/** 允许呼叫应用继续在另一个应用中启动的呼叫(需要 Android 9.0 及以上) */
public static final String ACCEPT_HANDOVER = "android.permission.ACCEPT_HANDOVER";

/**
* 权限组
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,14 @@ public void onRequestPermissionsResult(int requestCode, String[] permissions, in
}
}

if (!PermissionUtils.isAndroid9()) {
// 重新检查 Android 9.0 的一个新权限
if (Permission.ACCEPT_HANDOVER.equals(permission)) {
// 如果当前版本不符合最低要求,那么就重新进行权限检测
grantResults[i] = PermissionUtils.getPermissionStatus(getActivity(), permission);
}
}

if (!PermissionUtils.isAndroid8()) {
// 重新检查 Android 8.0 的两个新权限
if (Permission.ANSWER_PHONE_CALLS.equals(permission) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,12 @@ static Intent getWindowPermissionIntent(Context context) {
Intent intent = null;
if (PermissionUtils.isAndroid6()) {
intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
intent.setData(Uri.parse("package:" + context.getPackageName()));
// 在 Android 11 上面不能加包名跳转,因为就算加了也没有效果
// 还有人反馈在 Android 11 的 TV 模拟器上会出现崩溃的情况
// https://developer.android.google.cn/reference/android/provider/Settings#ACTION_MANAGE_OVERLAY_PERMISSION
if (!PermissionUtils.isAndroid11()) {
intent.setData(Uri.parse("package:" + context.getPackageName()));
}
}

if (intent == null || !PermissionUtils.areActivityIntent(context, intent)) {
Expand Down
29 changes: 26 additions & 3 deletions library/src/main/java/com/hjq/permissions/PermissionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ static boolean isAndroid10() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q;
}

/**
* 是否是 Android 9.0 及以上版本
*/
static boolean isAndroid9() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.P;
}

/**
* 是否是 Android 8.0 及以上版本
*/
Expand Down Expand Up @@ -226,7 +233,7 @@ static boolean isGrantedPermission(Context context, String permission) {
}

if (!isAndroid10()) {
// 检测 10.0 的三个新权限,如果当前版本不符合最低要求,那么就用旧权限进行检测
// 检测 10.0 的三个新权限
if (Permission.ACCESS_BACKGROUND_LOCATION.equals(permission) ||
Permission.ACCESS_MEDIA_LOCATION.equals(permission)) {
return true;
Expand All @@ -237,8 +244,15 @@ static boolean isGrantedPermission(Context context, String permission) {
}
}

if (!isAndroid9()) {
// 检测 9.0 的一个新权限
if (Permission.ACCEPT_HANDOVER.equals(permission)) {
return true;
}
}

if (!isAndroid8()) {
// 检测 8.0 的两个新权限,如果当前版本不符合最低要求,那么就用旧权限进行检测
// 检测 8.0 的两个新权限
if (Permission.ANSWER_PHONE_CALLS.equals(permission)) {
return context.checkSelfPermission(Permission.PROCESS_OUTGOING_CALLS) == PackageManager.PERMISSION_GRANTED;
}
Expand Down Expand Up @@ -294,7 +308,7 @@ private static boolean isPermissionPermanentDenied(Activity activity, String per
}

if (!isAndroid10()) {
// 检测 10.0 的三个新权限,如果当前版本不符合最低要求,那么就用旧权限进行检测
// 检测 10.0 的三个新权限
if (Permission.ACCESS_BACKGROUND_LOCATION.equals(permission) ||
Permission.ACCESS_MEDIA_LOCATION.equals(permission)) {
return false;
Expand All @@ -306,6 +320,13 @@ private static boolean isPermissionPermanentDenied(Activity activity, String per
}
}

if (!isAndroid9()) {
// 检测 9.0 的一个新权限
if (Permission.ACCEPT_HANDOVER.equals(permission)) {
return false;
}
}

if (!isAndroid8()) {
// 检测 8.0 的两个新权限,如果当前版本不符合最低要求,那么就用旧权限进行检测
if (Permission.ANSWER_PHONE_CALLS.equals(permission) ) {
Expand Down Expand Up @@ -513,6 +534,8 @@ static void checkTargetSdkVersion(Context context, List<String> requestPermissio
if (requestPermissions.contains(Permission.MANAGE_EXTERNAL_STORAGE)) {
// 必须设置 targetSdkVersion >= 30 才能正常检测权限,否则请使用 Permission.Group.STORAGE 来申请存储权限
targetSdkMinVersion = Build.VERSION_CODES.R;
} else if (requestPermissions.contains(Permission.ACCEPT_HANDOVER)) {
targetSdkMinVersion = Build.VERSION_CODES.P;
} else if (requestPermissions.contains(Permission.ACCESS_BACKGROUND_LOCATION) ||
requestPermissions.contains(Permission.ACTIVITY_RECOGNITION) ||
requestPermissions.contains(Permission.ACCESS_MEDIA_LOCATION)) {
Expand Down
29 changes: 14 additions & 15 deletions library/src/main/java/com/hjq/permissions/XXPermissions.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ public static void setDebugMode(boolean debug) {
sDebugMode = debug;
}


/** Activity 对象 */
private FragmentActivity mActivity;

Expand Down Expand Up @@ -199,40 +198,40 @@ public static void startApplicationDetails(Fragment fragment) {
/**
* 跳转到应用权限设置页
*
* @param deniedPermissions 没有授予或者被拒绝的权限组
* @param permissions 没有授予或者被拒绝的权限组
*/
public static void startPermissionActivity(Context context, String... deniedPermissions) {
startPermissionActivity(context, PermissionUtils.asArrayList(deniedPermissions));
public static void startPermissionActivity(Context context, String... permissions) {
startPermissionActivity(context, PermissionUtils.asArrayList(permissions));
}

public static void startPermissionActivity(Context context, List<String> deniedPermissions) {
public static void startPermissionActivity(Context context, List<String> permissions) {
Activity activity = PermissionUtils.getFragmentActivity(context);
if (activity != null) {
startPermissionActivity(activity, deniedPermissions);
startPermissionActivity(activity, permissions);
return;
}
Intent intent = PermissionSettingPage.getSmartPermissionIntent(context, deniedPermissions);
Intent intent = PermissionSettingPage.getSmartPermissionIntent(context, permissions);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}

public static void startPermissionActivity(Activity activity, String... deniedPermission) {
startPermissionActivity(activity, PermissionUtils.asArrayList(deniedPermission));
public static void startPermissionActivity(Activity activity, String... permissions) {
startPermissionActivity(activity, PermissionUtils.asArrayList(permissions));
}

public static void startPermissionActivity(Activity activity, List<String> deniedPermissions) {
activity.startActivityForResult(PermissionSettingPage.getSmartPermissionIntent(activity, deniedPermissions), REQUEST_CODE);
public static void startPermissionActivity(Activity activity, List<String> permissions) {
activity.startActivityForResult(PermissionSettingPage.getSmartPermissionIntent(activity, permissions), REQUEST_CODE);
}

public static void startPermissionActivity(Fragment fragment, String... deniedPermission) {
startPermissionActivity(fragment, PermissionUtils.asArrayList(deniedPermission));
public static void startPermissionActivity(Fragment fragment, String... permissions) {
startPermissionActivity(fragment, PermissionUtils.asArrayList(permissions));
}

public static void startPermissionActivity(Fragment fragment, List<String> deniedPermissions) {
public static void startPermissionActivity(Fragment fragment, List<String> permissions) {
FragmentActivity activity = fragment.getActivity();
if (activity == null) {
return;
}
fragment.startActivityForResult(PermissionSettingPage.getSmartPermissionIntent(activity, deniedPermissions), REQUEST_CODE);
fragment.startActivityForResult(PermissionSettingPage.getSmartPermissionIntent(activity, permissions), REQUEST_CODE);
}
}

0 comments on commit f354124

Please sign in to comment.