EasyPermissions 简介
EasyPermissions是一个简化Android 6.0(API 23)及以上系统运行时权限(Runtime Permissions)管理的开源库。它封装了复杂的权限请求逻辑,提供简洁易用的API,帮助开发者快速集成权限管理功能。
核心特性
- 简洁API:一行代码完成权限请求
- 自动处理:内置权限检查、请求和结果处理流程
- 拒绝处理:智能识别永久拒绝状态,引导用户到设置页面
- 注解支持:通过
@AfterPermissionGranted注解自动执行授权后逻辑 - 兼容性:支持Activity和Fragment,兼容AndroidX
权限管理流程图
适用场景
- 需要访问危险权限(Dangerous Permissions)的应用
- 关注用户体验的应用,需要优雅处理权限拒绝场景
- 希望减少重复代码的Android项目
### 2. 安装指南(docs/installation.md)
```markdown
# 安装 EasyPermissions
EasyPermissions支持多种集成方式,选择最适合你的项目的方式进行安装。
## 要求
- Android SDK 21+ (Android 5.0 Lollipop)
- Gradle 4.0+
## Gradle 集成(推荐)
### 步骤1:添加仓库
在项目根目录的`build.gradle`或`settings.gradle`中添加Maven仓库:
```groovy
allprojects {
repositories {
// ...其他仓库
maven { url 'https://jitpack.io' }
}
}
步骤2:添加依赖
在应用模块的build.gradle中添加依赖:
dependencies {
// ...其他依赖
implementation 'com.github.gh_mirrors.ea:easypermissions:latest.release'
}
提示:将
latest.release替换为具体版本号,如2.0.0,以确保构建稳定性。
手动集成
步骤1:克隆仓库
git clone https://gitcode.com/gh_mirrors/ea/easypermissions.git
步骤2:导入模块
- 在Android Studio中选择
File > New > Import Module - 选择克隆下来的仓库中的
easypermissions目录 - 在应用模块的
build.gradle中添加依赖:
dependencies {
implementation project(':easypermissions')
}
验证安装
添加依赖后,同步项目并检查是否能成功导入EasyPermissions类:
import pub.devrel.easypermissions.EasyPermissions;
如果没有报错,则说明安装成功。
### 3. 快速开始(docs/quick-start.md)
```markdown
# 快速开始:5分钟集成权限管理
本教程将展示如何使用EasyPermissions快速实现相机权限的请求和处理流程。
## 步骤1:添加权限声明
在`AndroidManifest.xml`中添加需要的权限:
```xml
<uses-permission android:name="android.permission.CAMERA" />
步骤2:实现回调接口
让你的Activity或Fragment实现EasyPermissions.PermissionCallbacks接口:
import pub.devrel.easypermissions.EasyPermissions;
import pub.devrel.easypermissions.PermissionCallbacks;
public class MainActivity extends AppCompatActivity implements PermissionCallbacks {
// ...
}
步骤3:重写权限结果方法
将权限请求结果转发给EasyPermissions处理:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// 将结果转发给EasyPermissions
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
步骤4:实现权限检查和请求
创建一个方法来检查和请求相机权限:
// 权限请求码(必须在0-255之间)
private static final int RC_CAMERA_PERM = 123;
private void checkCameraPermission() {
// 定义需要请求的权限
String[] perms = {Manifest.permission.CAMERA};
if (EasyPermissions.hasPermissions(this, perms)) {
// 已有权限,直接执行操作
openCamera();
} else {
// 无权限,请求权限
EasyPermissions.requestPermissions(
this, // Activity或Fragment实例
"需要相机权限来拍摄照片", // 权限请求 rationale
RC_CAMERA_PERM, // 请求码
perms // 权限数组
);
}
}
步骤5:实现回调方法
处理权限授予和拒绝的情况:
@Override
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
// 权限被授予
if (requestCode == RC_CAMERA_PERM) {
openCamera();
}
}
@Override
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
// 权限被拒绝
Log.d("EasyPermissions", "权限被拒绝: " + perms);
// 检查是否有永久拒绝的权限
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
// 显示设置对话框,引导用户到应用设置中开启权限
new AppSettingsDialog.Builder(this).build().show();
}
}
步骤6:调用权限检查方法
在需要使用相机的地方调用checkCameraPermission():
Button takePhotoButton = findViewById(R.id.take_photo_button);
takePhotoButton.setOnClickListener(v -> checkCameraPermission());
步骤7:处理从设置返回的情况(可选)
如果实现了AppSettingsDialog,需要处理从设置页面返回的情况:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) {
// 从设置页面返回,重新检查权限
checkCameraPermission();
}
}
完整流程示意图
恭喜!你已经成功集成了EasyPermissions库来管理相机权限。这种模式可以应用于任何危险权限的管理。
### 4. API参考:EasyPermissions类(docs/api/EasyPermissions.md)
```markdown
# EasyPermissions 类
`EasyPermissions`是库的核心类,提供了权限检查、请求和结果处理的静态方法。
## 类定义
```java
public class EasyPermissions {
// 类内容
}
主要方法
1. hasPermissions()
检查是否拥有指定的权限。
方法签名:
public static boolean hasPermissions(
@NonNull Context context,
@Size(min = 1) @NonNull String... perms
)
参数:
context:上下文对象perms:一个或多个权限字符串(如Manifest.permission.CAMERA)
返回值:
true:所有权限都已授予false:至少有一个权限未授予
示例:
if (EasyPermissions.hasPermissions(this, Manifest.permission.CAMERA)) {
// 有权限,执行操作
} else {
// 无权限,请求权限
}
注意:
- 在Android M(API 23)以下设备上,始终返回
true - 上下文不能为
null,否则会抛出IllegalArgumentException
2. requestPermissions()
请求指定的权限,支持Activity和Fragment。
方法签名(Activity重载):
public static void requestPermissions(
@NonNull Activity host,
@NonNull String rationale,
@IntRange(from = 0, to = 255) int requestCode,
@Size(min = 1) @NonNull String... perms
)
方法签名(Fragment重载):
public static void requestPermissions(
@NonNull Fragment host,
@NonNull String rationale,
@IntRange(from = 0, to = 255) int requestCode,
@Size(min = 1) @NonNull String... perms
)
参数:
host:Activity或Fragment实例rationale:权限请求理由,将显示在权限对话框中requestCode:请求码(0-255之间)perms:要请求的权限数组
示例:
EasyPermissions.requestPermissions(
this, // Activity实例
"需要相机权限来拍摄照片", // 权限请求理由
RC_CAMERA_PERM, // 请求码
Manifest.permission.CAMERA // 权限
);
3. onRequestPermissionsResult()
处理权限请求结果,应在Activity或Fragment的同名方法中调用。
方法签名:
public static void onRequestPermissionsResult(
@IntRange(from = 0, to = 255) int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults,
@NonNull Object... receivers
)
参数:
requestCode:请求码permissions:请求的权限数组grantResults:权限授予结果数组receivers:实现了PermissionCallbacks接口的对象
示例:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// 将结果转发给EasyPermissions
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
4. somePermissionPermanentlyDenied()
检查是否有任何权限被永久拒绝(用户勾选了"不再询问")。
方法签名:
public static boolean somePermissionPermanentlyDenied(
@NonNull Activity host,
@NonNull List<String> deniedPermissions
)
public static boolean somePermissionPermanentlyDenied(
@NonNull Fragment host,
@NonNull List<String> deniedPermissions
)
参数:
host:Activity或Fragment实例deniedPermissions:被拒绝的权限列表
返回值:
true:至少有一个权限被永久拒绝false:所有被拒绝的权限都可以再次请求
示例:
@Override
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
new AppSettingsDialog.Builder(this).build().show();
}
}
回调接口
PermissionCallbacks
权限请求结果回调接口,需要由Activity或Fragment实现。
public interface PermissionCallbacks extends ActivityCompat.OnRequestPermissionsResultCallback {
void onPermissionsGranted(int requestCode, @NonNull List<String> perms);
void onPermissionsDenied(int requestCode, @NonNull List<String> perms);
}
方法说明:
onPermissionsGranted:当权限被授予时调用onPermissionsDenied:当权限被拒绝时调用
RationaleCallbacks
权限请求理由对话框的按钮点击回调接口。
public interface RationaleCallbacks {
void onRationaleAccepted(int requestCode);
void onRationaleDenied(int requestCode);
}
方法说明:
onRationaleAccepted:当用户点击理由对话框的"确定"按钮时调用onRationaleDenied:当用户点击理由对话框的"取消"按钮时调用
注解支持
@AfterPermissionGranted
用于标记当权限被授予后自动执行的方法。
注解定义:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AfterPermissionGranted {
int value(); // 请求码
}
使用示例:
@AfterPermissionGranted(RC_CAMERA_PERM)
private void openCamera() {
// 此方法将在权限被授予后自动调用
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, RC_CAMERA_REQUEST);
}
注意事项:
- 注解值必须与请求权限时使用的
requestCode一致 - 被注解的方法必须是无参数的
void方法 - 方法可以是
private的
方法调用流程图
异常处理
| 异常 | 原因 | 解决方案 |
|---|---|---|
| IllegalArgumentException | 上下文为null | 确保传递有效的Context对象 |
| RuntimeException | @AfterPermissionGranted注解的方法有参数 | 确保注解方法无参数 |
| RuntimeException | @AfterPermissionGranted注解的方法非void | 确保注解方法返回类型为void |
## 自动化文档生成:从代码到文档
### API文档自动提取
为了保持API文档与代码同步,我们可以使用Docusaurus的插件系统结合JavaDoc工具自动提取API信息。
1. **添加JavaDoc生成插件**
```bash
yarn add --dev docusaurus-plugin-javadoc
- 配置插件(docusaurus.config.js)
module.exports = {
// ...其他配置
plugins: [
[
'docusaurus-plugin-javadoc',
{
src: [
{
path: '../easypermissions/src/main/java',
packages: ['pub.devrel.easypermissions'],
},
],
dest: 'docs/api',
templates: './templates',
exclude: ['**/*Test.java'],
},
],
],
};
- 创建API文档生成脚本(package.json)
{
"scripts": {
"generate-api-docs": "docusaurus generate-api-docs",
"prebuild": "yarn generate-api-docs"
}
}
代码示例自动验证
为确保文档中的代码示例可正常运行,我们可以使用Docusaurus的代码块验证功能:
- 安装代码块验证插件
yarn add --dev docusaurus-plugin-codeblock-validation
- 配置插件(docusaurus.config.js)
module.exports = {
// ...其他配置
plugins: [
// ...其他插件
[
'docusaurus-plugin-codeblock-validation',
{
testCases: [
{
language: 'java',
testFunction: async (code) => {
// 简单的Java语法检查逻辑
return code.includes(';') && !code.includes('error');
}
}
]
}
]
]
};
版本管理:支持多版本文档
Docusaurus内置了版本管理功能,可以轻松维护不同版本的文档:
创建文档版本
# 创建1.0.0版本
yarn run docusaurus docs:version 1.0.0
# 创建2.0.0版本
yarn run docusaurus docs:version 2.0.0
版本配置(docusaurus.config.js)
module.exports = {
// ...其他配置
themeConfig: {
// ...其他主题配置
navbar: {
// ...其他导航项
items: [
// ...其他项
{
type: 'docsVersionDropdown',
position: 'right',
dropdownItemsAfter: [{to: '/versions', label: '所有版本'}],
dropdownActiveClassDisabled: true,
},
],
},
},
};
版本维护工作流
部署文档站
构建静态文件
yarn build
构建后的静态文件将生成在build目录下。
本地测试
yarn serve
访问http://localhost:3000查看构建结果。
部署到GitHub Pages
- 添加部署脚本(package.json)
{
"scripts": {
"deploy": "GIT_USER=<Your GitCode Username> USE_SSH=true yarn run docusaurus deploy"
}
}
- 执行部署
yarn deploy
部署到其他平台
Docusaurus生成的静态文件可以部署到任何支持静态网站托管的平台:
- GitCode Pages:与GitHub Pages类似
- Netlify:连接Git仓库自动部署
- Vercel:提供免费的静态网站托管
- 阿里云OSS:配置静态网站托管模式
- Nginx:直接部署到服务器
高级定制:打造个性化文档站
自定义主题
- 创建自定义CSS(src/css/custom.css)
/* 更改导航栏颜色 */
.navbar {
background-color: #2196f3;
}
/* 更改代码块样式 */
.prism-code {
font-size: 0.9rem;
border-radius: 8px;
}
/* 自定义标题样式 */
h1, h2, h3 {
color: #212121;
font-weight: 600;
}
- 添加自定义组件
创建一个自定义的代码块复制按钮组件,提升用户体验。
集成搜索功能
Docusaurus默认提供基于Algolia的搜索功能,配置步骤:
- 创建Algolia账号并获取API密钥
- 配置docusaurus.config.js
module.exports = {
themeConfig: {
algolia: {
apiKey: '你的Algolia API密钥',
indexName: 'easypermissions',
appId: '你的Algolia应用ID',
},
},
};
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



