XXPermissions
Android Permissions Framework, Adapt to Android 16
Install / Use
/learn @getActivity/XXPermissionsREADME
English Doc
权限请求框架

-
项目地址:Github
-
博文地址:月下载 40 万次的框架是怎么练成的?
-
可以扫码下载 Demo 进行演示或者测试,如果扫码下载不了的,点击此处可直接下载








集成步骤
- 如果你的项目 Gradle 配置是在
7.0以下,需要在build.gradle文件中加入
allprojects {
repositories {
// JitPack 远程仓库:https://jitpack.io
maven { url 'https://jitpack.io' }
}
}
- 如果你的 Gradle 配置是
7.0及以上,则需要在settings.gradle文件中加入
dependencyResolutionManagement {
repositories {
// JitPack 远程仓库:https://jitpack.io
maven { url 'https://jitpack.io' }
}
}
- 配置完远程仓库后,在项目 app 模块下的
build.gradle文件中加入远程依赖
android {
// 支持 JDK 1.8 及以上
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
// 设备兼容框架:https://github.com/getActivity/DeviceCompat
implementation 'com.github.getActivity:DeviceCompat:2.3'
// 权限请求框架:https://github.com/getActivity/XXPermissions
implementation 'com.github.getActivity:XXPermissions:28.0'
}
Support 库兼容
- 方案一:沿用旧版本框架的远程依赖
dependencies {
// 设备兼容框架:https://github.com/getActivity/DeviceCompat
implementation 'com.github.getActivity:DeviceCompat:2.3'
// 权限请求框架:https://github.com/getActivity/XXPermissions
implementation 'com.github.getActivity:XXPermissions:26.8'
}
-
方案二:如果你的项目仍处于 Support 阶段,目前不方便转到 AndroidX 中来,但又想用最新版本的框架,可以使用 Google 提供的 JetifierStandalone 工具将已发布版本 Release 中的 aar 包通过反向模式转成 Support 版本的 aar 包来使用。
-
上述两种方案任选其一即可,但是仍旧不推荐你那样做,因为这些只是权宜之计,并非长久之计,框架后续的版本已不再支持 Support 项目,最好的方案是将项目迁移到 AndroidX。
-
将项目从 Support 迁移 AndroidX 相关的教程:AndroidX 踩坑指南
分区存储
- 如果项目已经适配了 Android 10 分区存储特性,请在
AndroidManifest.xml中加入
<manifest>
<application>
<!-- 告知 XXPermissions 当前项目已经适配了分区存储特性 -->
<meta-data
android:name="ScopedStorage"
android:value="true" />
</application>
</manifest>
-
如果当前项目没有适配这特性,那么这一步骤可以忽略
-
需要注意的是:这个选项是框架用于判断当前项目是否适配了分区存储,需要注意的是,如果你的项目已经适配了分区存储特性,可以使用
READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE来申请权限,如果你的项目还没有适配分区特性,就算申请了READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE权限也会导致无法正常读取外部存储上面的文件,如果你的项目没有适配分区存储,请使用MANAGE_EXTERNAL_STORAGE来申请权限,这样才能正常读取外部存储上面的文件,你如果想了解更多关于 Android 10 分区存储的特性,可以点击此处查看和学习。
框架混淆规则
- 框架已经在内部自动帮你添加了框架的混淆规则,在你添加框架的依赖远程库的时候,框架的混淆规则也会一同携带到你的项目中,你无需自己手动添加,具体的混淆规则内容 可点击此处查看
一句代码搞定权限请求,从未如此简单
- Java 用法示例
XXPermissions.with(this)
// 申请多个权限
.permission(PermissionLists.getRecordAudioPermission())
.permission(PermissionLists.getCameraPermission())
// 设置不触发错误检测机制(局部设置)
//.unchecked()
.request(new OnPermissionCallback() {
@Override
public void onResult(@NonNull List<IPermission> grantedList, @NonNull List<IPermission> deniedList) {
boolean allGranted = deniedList.isEmpty();
if (!allGranted) {
// 判断请求失败的权限是否被用户勾选了不再询问的选项
boolean doNotAskAgain = XXPermissions.isDoNotAskAgainPermissions(activity, deniedList);
// 在这里处理权限请求失败的逻辑
......
return;
}
// 在这里处理权限请求成功的逻辑
......
}
});
- Kotlin 用法示例
XXPermissions.with(this)
// 申请多个权限
.permission(PermissionLists.getRecordAudioPermission())
.permission(PermissionLists.getCameraPermission())
// 设置不触发错误检测机制(局部设置)
//.unchecked()
.request(object : OnPermissionCallback {
override fun onResult(grantedList: MutableList<IPermission>, deniedList: MutableList<IPermission>) {
val allGranted = deniedList.isEmpty()
if (!allGranted) {
// 判断请求失败的权限是否被用户勾选了不再询问的选项
val doNotAskAgain = XXPermissions.isDoNotAskAgainPermissions(activity, deniedList)
// 在这里处理权限请求失败的逻辑
// ......
return
}
// 在这里处理权限请求成功的逻辑
// ......
}
})
框架其他 API 介绍
// 判断一个或多个权限是否全部授予了
XXPermissions.isGrantedPermission(@NonNull Context context, @NonNull IPermission permission);
XXPermissions.isGrantedPermissions(@NonNull Context context, @NonNull IPermission[] permissions);
XXPermissions.isGrantedPermissions(@NonNull Context context, @NonNull List<IPermission> permissions);
// 从权限列表中获取已授予的权限
XXPermissions.getGrantedPermissions(@NonNull Context context, @NonNull IPermission[] permissions);
XXPermissions.getGrantedPermissions(@NonNull Context context, @NonNull List<IPermission> permissions);
// 从权限列表中获取没有授予的权限
XXPermissions.getDeniedPermissions(@NonNull Context context, @NonNull IPermission[] permissions);
XXPermissions.getDeniedPermissions(@NonNull Context context, @NonNull List<IPermission> permissions);
// 判断两个权限是否相等
XXPermissions.equalsPermission(@NonNull IPermission permission, @NonNull IPermission permission2);
XXPermissions.equalsPermission(@NonNull IPermission permission, @NonNull String permissionName);
XXPermissions.equalsPermission(@NonNull String permissionName1, @NonNull String permissionName2);
// 判断权限列表中是否包含某个权限
XXPermissions.containsPermission(@NonNull List<IPermission> permissions, @NonNull IPermission permission);
XXPermissions.containsPermission(@NonNull List<IPermission> permissions, @NonNull String permissionName);
// 判断某个权限是否为健康权限
XXPermissions.isHealthPermission(@NonNull IPermission permission);
// 判断一个或多个权限是否被勾选了《不再询问》的选项(一定要在权限申请的回调方法中调用才有效果)
XXPermissions.isDoNotAskAgainPermission(@NonNull Activity activity, @NonNull IPermission permission);
XXPermissions.isDoNotAskAgainPermissions(@NonNull Activity activity, @NonNull IPermission[] permissions);
XXPermissions.isDoNotAskAgainPermissions(@NonNull Activity activity, @NonNull List<IPermission> permissions);
// 跳转到权限设置页(Context 版本)
XXPermissions.startPermissionActivity(@NonNull Context context);
XXPermissions.startPermissionActivity(@NonNull Context context, @NonNull IPermission... permissions);
XXPermissions.startPermissionActivity(@NonNull Context context, @NonNull List<IPermission> permissions);
// 跳转到权限设置页(Activity 版本)
XXPermissions.startPermissionActivity(@NonNull Activity activity);
XXPermissions.startPermissionActivity(@NonNull Activity activity, @NonNull IPermission... permissions);
XXPermissions.startPermissionActivity(@NonNull Activity activity, @NonNull List<IPermission> permissions);
XXPermissions.startPermissionActivity(@NonNull Activity activity, @NonNull List<IPermission> permissions, @IntRange(from = 1, to = 65535) int requestCode);
XXPermissions.startPermissionActivity(@NonNull Activity activity, @NonNull IPermission permission, @Nullable OnPermissionCallback callback);
XXPermissions.startPermissionActivity(@NonNull Activity activity, @NonNull List<IPermission> permissions, @Nullable OnPermissionCallback callback);
// 跳转到权限设置页(Android Fragment 版本)
XXPermissions.startPermissionActivity(@NonNull Fragment fragment);
XXPermissions.startPermissionActivity(@NonNull Fragment fragment, @NonNull IPermission... permissions);
XXPermissions.startPermissionActivity(@NonNull Fragment fragment, @NonNull List<IPermission> permissions);
XXPermissions.startPermissionActivity(@NonNull Fragment fragment, @NonNull List<IPermission> permissions, @IntRange(from = 1, to = 65535) int requestCode);
XXPermissions.startPermissionActivity(@NonNull Fragment fragment, @NonNull IPermission permission, @Nullable OnPermissionCallback callback);
XXPermissions.startPermissionActivity(@NonNull Fragment fragment, @NonNull List<IPermission> permissions, @Nullable OnPermissionCallback callback);
// 跳转到权限设置页(AndroidX Fragment 版本)
XXPermissions.startPermissionActivity(@NonNull androidx.fragment.app.Fragment xFragment);
XXPermissions.startPermissionActivity(@NonNull androidx.fragment.app.Fragment xFragment, @NonNull IPermission... permissions);
XXPermissions.startPermissionActivity(@NonNull androidx.fragment.app.Fragment xFragment, @NonNull List<IPermission> permissions);
XXPermissions.startPermissionActivity(@NonNull androidx.fragment.app.Fragment xFragment, @NonNull List<IPermission> permissions, @IntRange(from = 1, to = 65535) int requestCo
