Skip to content

Commit

Permalink
适配 Android 14 权限
Browse files Browse the repository at this point in the history
修复极端情况下出现空指针的问题
优化框架部分代码命名和代码逻辑
优化除华为和荣耀外其他机型跳转勿扰权限设置页逻辑
新增限定外层传入权限字符串常量必须为指定的字段
  • Loading branch information
getActivity committed Oct 10, 2023
1 parent 59333a4 commit e1dc6ed
Show file tree
Hide file tree
Showing 35 changed files with 742 additions and 458 deletions.
4 changes: 2 additions & 2 deletions HelpDoc-en.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,8 @@ XXPermissions.with(this)
@Override
public void onDenied(@NonNull List<String> permissions, boolean doNotAskAgain) {
if (doNotAskAgain && permissions.contains(Permission.RECORD_AUDIO) &&
XXPermissions.isPermanentDenied(MainActivity.this, Permission.RECORD_AUDIO)) {
toast("Recording permission has been permanently denied");
XXPermissions.isDoNotAskAgainPermissions(MainActivity.this, Permission.RECORD_AUDIO)) {
toast("The recording permission request was denied, and the user checked Do not ask");
}
}
});
Expand Down
4 changes: 2 additions & 2 deletions HelpDoc-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,8 @@ XXPermissions.with(this)
@Override
public void onDenied(@NonNull List<String> permissions, boolean doNotAskAgain) {
if (doNotAskAgain && permissions.contains(Permission.RECORD_AUDIO) &&
XXPermissions.isPermanentDenied(MainActivity.this, Permission.RECORD_AUDIO)) {
toast("录音权限被永久拒绝了");
XXPermissions.isDoNotAskAgainPermissions(MainActivity.this, Permission.RECORD_AUDIO)) {
toast("录音权限请求被拒绝了,并且用户勾选了不再询问");
}
}
});
Expand Down
39 changes: 20 additions & 19 deletions README-en.md

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

* 博文地址:[一句代码搞定权限请求,从未如此简单](https://www.jianshu.com/p/c69ff8a445ed)

* 可以扫码下载 Demo 进行演示或者测试,如果扫码下载不了的,[点击此处可直接下载](https://github.com/getActivity/XXPermissions/releases/download/18.3/XXPermissions.apk)
* 可以扫码下载 Demo 进行演示或者测试,如果扫码下载不了的,[点击此处可直接下载](https://github.com/getActivity/XXPermissions/releases/download/18.5/XXPermissions.apk)

![](picture/zh/download_demo_apk_qr_code.png)

Expand Down Expand Up @@ -61,7 +61,7 @@ android {
dependencies {
// 权限请求框架:https://github.com/getActivity/XXPermissions
implementation 'com.github.getActivity:XXPermissions:18.3'
implementation 'com.github.getActivity:XXPermissions:18.5'
}
```

Expand Down Expand Up @@ -183,8 +183,8 @@ XXPermissions.getDenied(Context context, String... permissions);
// 判断某个权限是否为特殊权限
XXPermissions.isSpecial(String permission);

// 判断一个或多个权限是否被永久拒绝了(一定要在权限申请的回调方法中调用才有效果)
XXPermissions.isPermanentDenied(Activity activity, String... permissions);
// 判断一个或多个权限是否被勾选了《不再询问》的选项(一定要在权限申请的回调方法中调用才有效果)
XXPermissions.isDoNotAskAgainPermissions(Activity activity, String... permissions);

// 跳转到应用权限设置页
XXPermissions.startPermissionActivity(Context context, String... permissions);
Expand Down Expand Up @@ -223,9 +223,9 @@ XXPermissions.setInterceptor(new IPermissionInterceptor() {});

| 适配细节 | [XXPermissions](https://github.com/getActivity/XXPermissions) | [AndPermission](https://github.com/yanzhenjie/AndPermission) | [PermissionX](https://github.com/guolindev/PermissionX) | [AndroidUtilCode-PermissionUtils](https://github.com/Blankj/AndroidUtilCode) | [PermissionsDispatcher](https://github.com/permissions-dispatcher/PermissionsDispatcher) | [RxPermissions](https://github.com/tbruyelle/RxPermissions) | [EasyPermissions](https://github.com/googlesamples/easypermissions) |
| :--------: | :------------: | :------------: | :------------: | :------------: | :------------: | :------------: | :------------: |
| 对应版本 | 18.3 | 2.0.3 | 1.7.1 | 1.31.0 | 4.9.2 | 0.12 | 3.0.0 |
| 对应版本 | 18.5 | 2.0.3 | 1.7.1 | 1.31.0 | 4.9.2 | 0.12 | 3.0.0 |
| 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/permissions-dispatcher/PermissionsDispatcher.svg)](https://github.com/permissions-dispatcher/PermissionsDispatcher/issues) | [![](https://img.shields.io/github/issues/tbruyelle/RxPermissions.svg)](https://github.com/tbruyelle/RxPermissions/issues) | [![](https://img.shields.io/github/issues/googlesamples/easypermissions.svg)](https://github.com/googlesamples/easypermissions/issues) |
| 框架体积 | 82 KB | 127 KB | 97 KB | 500 KB | 99 KB | 28 KB | 48 KB |
| 框架体积 | 85 KB | 127 KB | 97 KB | 500 KB | 99 KB | 28 KB | 48 KB |
| 框架维护状态 |**维护中**| 停止维护 | 停止维护 | 停止维护 | 停止维护 | 停止维护 | 停止维护 |
| 闹钟提醒权限 ||||||||
| 所有文件管理权限 ||||||||
Expand All @@ -240,6 +240,7 @@ XXPermissions.setInterceptor(new IPermissionInterceptor() {});
| 查看应用使用情况权限 ||||||||
| VPN 权限 ||||||||
| 读取应用列表权限 ||||||||
| Android 14 危险权限 ||||||||
| Android 13 危险权限 ||||||||
| Android 12 危险权限 ||||||||
| Android 11 危险权限 ||||||||
Expand Down Expand Up @@ -367,7 +368,7 @@ XXPermissions.setInterceptor(new IPermissionInterceptor() {});

#### 框架亮点

* 一马当先:首款适配 Android 13 的权限请求框架
* 一马当先:首款适配 Android 14 的权限请求框架

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

Expand Down
14 changes: 7 additions & 7 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 33
compileSdkVersion 34

defaultConfig {
applicationId "com.hjq.permissions.demo"
minSdkVersion 16
targetSdkVersion 33
versionCode 1803
versionName "18.3"
targetSdkVersion 34
versionCode 1805
versionName "18.5"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

Expand Down Expand Up @@ -42,9 +42,9 @@ android {
}
}

applicationVariants.all { variant ->
applicationVariants.configureEach { variant ->
// apk 输出文件名配置
variant.outputs.all { output ->
variant.outputs.configureEach { output ->
outputFileName = rootProject.getName() + '.apk'
}
}
Expand All @@ -61,7 +61,7 @@ dependencies {
implementation 'com.android.support:appcompat-v7:28.0.0'

// 吐司框架:https://github.com/getActivity/Toaster
implementation 'com.github.getActivity:Toaster:12.3'
implementation 'com.github.getActivity:Toaster:12.5'

// 内存泄漏检测:https://github.com/square/leakcanary
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12'
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />

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

<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />

Expand Down
5 changes: 2 additions & 3 deletions app/src/main/java/com/hjq/permissions/demo/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,10 @@
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.hjq.toast.Toaster;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
Expand Down Expand Up @@ -285,6 +283,7 @@ public void run() {
.permission(Permission.READ_MEDIA_IMAGES)
.permission(Permission.READ_MEDIA_VIDEO)
.permission(Permission.READ_MEDIA_AUDIO)
.permission(Permission.READ_MEDIA_VISUAL_USER_SELECTED)
.interceptor(new PermissionInterceptor())
.request(new OnPermissionCallback() {

Expand Down Expand Up @@ -749,7 +748,7 @@ private void getAppList() {
Log.i("XXPermissions", "应用包名:" + info.packageName);
}
} catch (Throwable t) {
t.printStackTrace();;
t.printStackTrace();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;

import com.hjq.permissions.Permission;

import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -67,7 +65,8 @@ public static List<String> permissionsToNames(Context context, List<String> perm
break;
}
case Permission.READ_MEDIA_IMAGES:
case Permission.READ_MEDIA_VIDEO: {
case Permission.READ_MEDIA_VIDEO:
case Permission.READ_MEDIA_VISUAL_USER_SELECTED:{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
String hint = context.getString(R.string.common_permission_image_and_video);
if (!permissionNames.contains(hint)) {
Expand Down
21 changes: 18 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,25 @@ allprojects {
jcenter()
}

// 将构建文件统一输出到项目根目录下的 build 文件夹
setBuildDir(new File(rootDir, "build/${path.replaceAll(':', '/')}"))
// 读取 local.properties 文件配置
def properties = new Properties()
def localPropertiesFile = rootProject.file("local.properties")
if (localPropertiesFile.exists()) {
localPropertiesFile.withInputStream { inputStream ->
properties.load(inputStream)
}
}

String buildDirPath = properties.getProperty("build.dir")
if (buildDirPath != null && buildDirPath != "") {
// 将构建文件统一输出到指定的目录下
setBuildDir(new File(buildDirPath, rootProject.name + "/build/${path.replaceAll(':', '/')}"))
} else {
// 将构建文件统一输出到项目根目录下的 build 文件夹
setBuildDir(new File(rootDir, "build/${path.replaceAll(':', '/')}"))
}
}

task clean(type: Delete) {
tasks.register('clean', Delete) {
delete rootProject.buildDir
}
21 changes: 12 additions & 9 deletions library/build.gradle
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
apply plugin: 'com.android.library'

android {
compileSdkVersion 33
compileSdkVersion 34

defaultConfig {
minSdkVersion 14
versionCode 1803
versionName "18.3"
versionCode 1805
versionName "18.5"
}

// 使用 JDK 1.8
Expand All @@ -19,9 +19,9 @@ android {
abortOnError false
}

android.libraryVariants.all { variant ->
android.libraryVariants.configureEach { variant ->
// aar 输出文件名配置
variant.outputs.all { output ->
variant.outputs.configureEach { output ->
outputFileName = "${rootProject.name}-${android.defaultConfig.versionName}.aar"
}
}
Expand All @@ -45,23 +45,26 @@ dependencies {
compileOnly 'com.android.support:support-fragment:24.2.0'
}

tasks.withType(Javadoc) {
tasks.withType(Javadoc).configureEach {
// prevent Javadoc from failing gradle build:https://stackoverflow.com/questions/35435173/prevent-javadoc-from-failing-gradle-build
failOnError false
options.addStringOption('Xdoclint:none', '-quiet')
options.addStringOption('encoding', 'UTF-8')
options.addStringOption('charSet', 'UTF-8')
}

task sourcesJar(type: Jar) {
tasks.register('sourcesJar', Jar) {
from android.sourceSets.main.java.srcDirs
classifier = 'sources'
}

task javadoc(type: Javadoc) {
tasks.register('javadoc', Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}

task javadocJar(type: Jar, dependsOn: javadoc) {
tasks.register('javadocJar', Jar) {
dependsOn javadoc
classifier = 'javadoc'
from javadoc.destinationDir
}
Expand Down
58 changes: 41 additions & 17 deletions library/src/main/java/com/hjq/permissions/AndroidManifestInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import android.content.pm.PackageInfo;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -39,35 +38,60 @@ final class AndroidManifestInfo {

static final class UsesSdkInfo {

public int minSdkVersion;
/** 最小安装版本要求 **/
int minSdkVersion;
}

static final class PermissionInfo {

/** {@link PackageInfo#REQUESTED_PERMISSION_NEVER_FOR_LOCATION} */
private static final int REQUESTED_PERMISSION_NEVER_FOR_LOCATION = 0x00010000;
/** 不需要请求地理位置标志 */
private static final int REQUESTED_PERMISSION_NEVER_FOR_LOCATION;

public String name;
public int maxSdkVersion;
public int usesPermissionFlags;
static {
if (AndroidVersion.isAndroid12()) {
REQUESTED_PERMISSION_NEVER_FOR_LOCATION = PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION;
} else {
REQUESTED_PERMISSION_NEVER_FOR_LOCATION = 0x00010000;
}
}

public boolean neverForLocation() {
/** 权限名称 */
String name;
/** 最大生效 sdk 版本 */
int maxSdkVersion;
/** 权限使用标志 */
int usesPermissionFlags;

/**
* 是否不会用当前权限需要推导地理位置
*/
boolean neverForLocation() {
return (usesPermissionFlags & REQUESTED_PERMISSION_NEVER_FOR_LOCATION) != 0;
}
}

final static class ApplicationInfo {
public String name;
public boolean requestLegacyExternalStorage;
static final class ApplicationInfo {

/** 应用的类名 */
String name;
/** 是否忽略分区存储特性 */
boolean requestLegacyExternalStorage;
}

final static class ActivityInfo {
public String name;
public boolean supportsPictureInPicture;
static final class ActivityInfo {

/** 活动的类名 */
String name;
/** 窗口是否支持画中画 */
boolean supportsPictureInPicture;
}

final static class ServiceInfo {
public String name;
public String permission;
static final class ServiceInfo {

/** 服务的类名 */
String name;

/** 服务所使用到的权限 */
String permission;
}
}
10 changes: 9 additions & 1 deletion library/src/main/java/com/hjq/permissions/AndroidVersion.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
@SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
final class AndroidVersion {

static final int ANDROID_14 = Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
static final int ANDROID_13 = Build.VERSION_CODES.TIRAMISU;
static final int ANDROID_12_L = Build.VERSION_CODES.S_V2;
static final int ANDROID_12 = Build.VERSION_CODES.S;
Expand Down Expand Up @@ -47,6 +48,13 @@ static int getTargetSdkVersionCode(Context context) {
return context.getApplicationInfo().targetSdkVersion;
}

/**
* 是否是 Android 14 及以上版本
*/
static boolean isAndroid14() {
return Build.VERSION.SDK_INT >= ANDROID_14;
}

/**
* 是否是 Android 13 及以上版本
*/
Expand Down Expand Up @@ -111,7 +119,7 @@ static boolean isAndroid6() {
}

/**
* 是否是 Android 5.0 及以上版本
* 是否是 Android 5.1 及以上版本
*/
static boolean isAndroid5_1() {
return Build.VERSION.SDK_INT >= ANDROID_5_1;
Expand Down
Loading

0 comments on commit e1dc6ed

Please sign in to comment.