前言
在App的開(kāi)發(fā)中我們離不開(kāi)動(dòng)態(tài)權(quán)限申請(qǐng),官方的寫(xiě)法是在Activity回調(diào)結(jié)果番川,雖然很標(biāo)準(zhǔn)到涂,但是很繁瑣。
今天我們就自己動(dòng)手?jǐn)]一個(gè)Android動(dòng)態(tài)權(quán)限申請(qǐng)庫(kù)颁督。
動(dòng)態(tài)權(quán)限的工作流程
首先通過(guò) ActivityCompat.checkSelfPermission()
來(lái)檢查用戶(hù)是否已經(jīng)授權(quán)践啄,未授權(quán)再通過(guò) ActivityCompat.requestPermissions()
去申請(qǐng)權(quán)限。之后在 onRequestPermissionsResult()
獲取到申請(qǐng)結(jié)果沉御,如果被用戶(hù)拒絕再調(diào)用 shouldShowRequestPermissionRationale()
判斷是否不再提示權(quán)限彈窗屿讽。
- checkSelfPermission
- requestPermissions
- onRequestPermissionsResult
- shouldShowRequestPermissionRationale
實(shí)戰(zhàn)
設(shè)計(jì)回調(diào)接口
因?yàn)楣俜降膶?xiě)法太不響應(yīng)式編程,所以我們要封裝一個(gè)符合響應(yīng)式編程的動(dòng)態(tài)權(quán)限申請(qǐng)庫(kù)吠裆。
既然要符合響應(yīng)式編程伐谈,當(dāng)然是先編寫(xiě)回調(diào)接口,而動(dòng)態(tài)權(quán)限申請(qǐng)會(huì)返回三種狀態(tài) 允許硫痰,拒絕衩婚,不再提示 ,所以接口設(shè)計(jì)如下:
interface PermissionsCallback {
fun allow()
fun deny()
fun denyAndNotAskAgain()
}
編寫(xiě)動(dòng)態(tài)權(quán)限申請(qǐng)方法
因?yàn)槭琼憫?yīng)式編程嘛效斑,那肯定 方法(所需權(quán)限非春, 回調(diào)接口) 。
那么如何將權(quán)限和回調(diào)接口關(guān)聯(lián)呢?
我們?cè)谡{(diào)用 requestPermissions
申請(qǐng)權(quán)限時(shí)需要傳入 permissions 和 requestCode 奇昙,因此我們就可以通過(guò) requestCode 做回調(diào)接口的關(guān)聯(lián)护侮,代碼如下:
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()
}
接著我們?cè)?onRequestPermissionsResult()
中通過(guò) requestCode 從 Map 獲取到 permissionsCallback 并進(jìn)行相應(yīng)的處理,代碼如下:
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()
}
}
}
使用動(dòng)態(tài)權(quán)限申請(qǐng)庫(kù)
至此動(dòng)態(tài)權(quán)限申請(qǐng)庫(kù)核心代碼已經(jīng)編寫(xiě)完成储耐,在需要權(quán)限的地方調(diào)用 requestForPermissions
申請(qǐng)即可羊初,代碼如下:
requestForPermissions(
arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
),
object : PermissionsCallback {
override fun allow() {
}
override fun deny() {
}
override fun denyAndNotAskAgain() {
}
}
)
完整的代碼已經(jīng)上傳 github ,有需要可自行查看什湘。
Thanks
以上就是本篇文章的全部?jī)?nèi)容长赞,如有問(wèn)題歡迎指出,我們一起進(jìn)步闽撤。
如果喜歡的話希望點(diǎn)個(gè)贊吧得哆,您的鼓勵(lì)是我前進(jìn)的動(dòng)力。
謝謝~~
項(xiàng)目地址
- github: ActivityResultHelper