1). 创建该框架缘由
系统提供权限请求较为繁琐,此框架专注于解决权限请求繁琐问题。
2. 实现思路
- 使用注解在类上注解,并提供待请求的权限与请求码
- 在onCreate方法中请求权限
- 在onRequestPermissionsResult方法中进行权限结果的处理
- 使用注解在方法上注解,参数提供拒绝/不再提示/成功权限信息
3). 创建注解Permissions
注解使用的位置为类名,且在程序运行时.
参数一:需要请求权限的列表
参数二:请求码
/**
* Android 6.0 权限注解框架
*
* @Retention 运行时注解
* @Target 设置注解位置 -- 类
*
* @param value 请求权限数组
* @param value 请求码
*/
@Retention(AnnotationRetention.RUNTIME)
@Target(allowedTargets = [AnnotationTarget.CLASS])
annotation class Permissions(
/** 权限列表 */
val value: Array<String>,
/** 权限请求码 */
val code: Int
)
4). 创建注解拒绝权限PermissionDenied
使用位置为方法,程序运行时注解
参数一:权限请求码
/**
* 拒绝权限注解
* @Retention 运行时注解
* @Target 注解位置
*
* @param value 请求码
*/
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class PermissionDenied(val value: Int)
5). 创建注解不再提示权限PermissionNotShow
注解使用位置为方法,程序运行时注解
参数一:权限请求码
/**
* 不再提示注解
* @Retention 运行时注解
* @Target 注解位置
*
* @param value 请求码
*/
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class PermissionNotShow(val value: Int)
6). 创建成功注解PermissionSucceed
/**
* 注解权限成功
*
* @param value 请求码
*
* @Retention 运行时注解
* @Target 注解位置
*/
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class PermissionSucceed(val value: Int)
7). 请求权限
- 从当前的Activity中获取Permissions注解的信息
- 获取待请求权限的列表
- 遍历检测待请求权限是否已经获取到
- 请求未获取到的权限
/**
* 初始化权限界面
* @param any 当前页面
*/
fun requestPermission(any: Any) {
// 检测系统版本
if (isVersionOverM()) {
// 获取注解
val annotation = getActivity(any).javaClass.getAnnotation(Permissions::class.java)
// 判断注解是否为空
if (annotation != null) {
// 权限信息
val permissions = annotation.value
// 创建待申请权限数组
var request: List<String> = ArrayList()
permissions.forEach { permission ->
// L.d(permission)
// 检测自身是否具有该权限
val selfPermission = ContextCompat.checkSelfPermission(getActivity(any), permission)
// 如果没有该权限, 则添加进待申请的权限列表
if (selfPermission != PackageManager.PERMISSION_GRANTED) {
request += permission
}
}
// request.forEach { permission -> L.d(permission) }
// 判断待请求的权限数组是否为空
if (request.isNotEmpty()) {
// 不为空则请求权限
ActivityCompat.requestPermissions(getActivity(any), request.toTypedArray(), annotation.code)
} else {
// 获取成功
execPermissionSucceed(any, annotation.code)
}
}
}
}
8). 处理权限请求结果
- 检测相对应的权限是否被获取
- 如果未授予,则判断是否勾选不再提示,若勾选则加入不再提示列表; 若未勾选, 则加入拒绝权限列表
- 查找相应的方法并处理其结果
/**
* 请求权限结果
*/
fun onRequestPermissionsResult(any: Any, requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
// 检测系统版本
if (isVersionOverM()) {
// 判断权限列表是否为空
if (permissions.isNotEmpty()) {
// 被用户拒绝的权限数组
var deniedPermissions: List<String> = ArrayList()
// 被用户勾选不再提示的权限数组
var notShowPermissions: List<String> = ArrayList()
// 遍历请求的权限
for (i in 0 until permissions.size) {
// 检测未允许的权限
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
if (!ActivityCompat.shouldShowRequestPermissionRationale(getActivity(any), permissions[i])) {
// 添加到不再提示列表
notShowPermissions += permissions[i]
} else {
// 添加进入拒绝权限数组
deniedPermissions += permissions[i]
}
}
}
when {
// 拒绝的权限不为空时
deniedPermissions.isNotEmpty() -> {
// 执行拒绝权限的方法
// L.d("=================拒绝========================")
execPermission(any, requestCode, State.DENIED, deniedPermissions)
}
// 不再提示权限列表不为空
notShowPermissions.isNotEmpty() -> {
// 执行不再提示权限的方法
// L.d("================不再提示======================")
execPermission(any, requestCode, State.NOT_SHOW, notShowPermissions)
}
// 权限请求成功
else -> {
// L.d("================请求成功======================")
execPermissionSucceed(any, requestCode)
}
}
}
}
}