前言
在App的开发中我们离不开动态权限申请,官方的写法是在Activity回调结果,虽然很标准,但是很繁琐。
今天我们就自己动手撸一个Android动态权限申请库。
动态权限的工作流程
首先通过 ActivityCompat.checkSelfPermission()
来检查用户是否已经授权,未授权再通过 ActivityCompat.requestPermissions()
去申请权限。之后在 onRequestPermissionsResult()
获取到申请结果,如果被用户拒绝再调用 shouldShowRequestPermissionRationale()
判断是否不再提示权限弹窗。
- checkSelfPermission
- requestPermissions
- onRequestPermissionsResult
- shouldShowRequestPermissionRationale
实战
设计回调接口
因为官方的写法太不响应式编程,所以我们要封装一个符合响应式编程的动态权限申请库。
既然要符合响应式编程,当然是先编写回调接口,而动态权限申请会返回三种状态 允许,拒绝,不再提示 ,所以接口设计如下:
interface PermissionsCallback {
fun allow()
fun deny()
fun denyAndNotAskAgain()
}
编写动态权限申请方法
因为是响应式编程嘛,那肯定 方法(所需权限, 回调接口) 。
那么如何将权限和回调接口关联呢?
我们在调用 requestPermissions
申请权限时需要传入 permissions 和 requestCode ,因此我们就可以通过 requestCode 做回调接口的关联,代码如下:
private val permissionsCallbacks: MutableMap<Int, PermissionsCallback?> = HashMap()
fun requestForPermissions(permissions: Array<String>, callback: PermissionsCallback?) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
for (permission in permissions) {
val result = ActivityCompat.checkSelfPermission(requireContext(), permission)
if (result == PackageManager.PERMISSION_DENIED) {
val requestCode = Random().nextInt(0x0000FFFF)
permissionsCallbacks[requestCode] = callback
requestPermissions(permissions, requestCode)
return
}
}
}
callback?.allow()
}
接着我们在 onRequestPermissionsResult()
中通过 requestCode 从 Map 获取到 permissionsCallback 并进行相应的处理,代码如下:
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
permissionsCallbacks[requestCode]?.apply {
val length: Int = grantResults.size
for (i in 0 until length) {
if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(
requireContext() as Activity,
permissions[i]
)
) {
denyAndNotAskAgain()
} else {
deny()
}
return
}
}
if (length > 0) {
allow()
}
}
}
使用动态权限申请库
至此动态权限申请库核心代码已经编写完成,在需要权限的地方调用 requestForPermissions
申请即可,代码如下:
requestForPermissions(
arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
),
object : PermissionsCallback {
override fun allow() {
}
override fun deny() {
}
override fun denyAndNotAskAgain() {
}
}
)
完整的代码已经上传 github ,有需要可自行查看。
Thanks
以上就是本篇文章的全部内容,如有问题欢迎指出,我们一起进步。
如果喜欢的话希望点个赞吧,您的鼓励是我前进的动力。
谢谢~~
项目地址
- github: ActivityResultHelper