超詳細(xì) —— 自己動(dòng)手?jǐn)]一個(gè)Android動(dòng)態(tài)權(quán)限申請庫

前言

在App的開發(fā)中我們離不開動(dòng)態(tài)權(quán)限申請,官方的寫法是在Activity回調(diào)結(jié)果,雖然很標(biāo)準(zhǔn),但是很繁瑣。
今天我們就自己動(dòng)手?jǐn)]一個(gè)Android動(dòng)態(tài)權(quán)限申請庫。

動(dòng)態(tài)權(quán)限的工作流程

首先通過 ActivityCompat.checkSelfPermission() 來檢查用戶是否已經(jīng)授權(quán),未授權(quán)再通過 ActivityCompat.requestPermissions() 去申請權(quán)限。之后在 onRequestPermissionsResult() 獲取到申請結(jié)果,如果被用戶拒絕再調(diào)用 shouldShowRequestPermissionRationale() 判斷是否不再提示權(quán)限彈窗。

  • checkSelfPermission
  • requestPermissions
  • onRequestPermissionsResult
  • shouldShowRequestPermissionRationale

實(shí)戰(zhàn)

設(shè)計(jì)回調(diào)接口

因?yàn)楣俜降膶懛ㄌ豁憫?yīng)式編程,所以我們要封裝一個(gè)符合響應(yīng)式編程的動(dòng)態(tài)權(quán)限申請庫。
既然要符合響應(yīng)式編程,當(dāng)然是先編寫回調(diào)接口,而動(dòng)態(tài)權(quán)限申請會(huì)返回三種狀態(tài) 允許,拒絕,不再提示 ,所以接口設(shè)計(jì)如下:

interface PermissionsCallback {
    fun allow()
    fun deny()
    fun denyAndNotAskAgain()
}

編寫動(dòng)態(tài)權(quán)限申請方法

因?yàn)槭琼憫?yīng)式編程嘛,那肯定 方法(所需權(quán)限, 回調(diào)接口) 。
那么如何將權(quán)限和回調(diào)接口關(guān)聯(lián)呢?
我們在調(diào)用 requestPermissions 申請權(quán)限時(shí)需要傳入 permissionsrequestCode ,因此我們就可以通過 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()
}

接著我們在 onRequestPermissionsResult() 中通過 requestCodeMap 獲取到 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)限申請庫

至此動(dòng)態(tài)權(quán)限申請庫核心代碼已經(jīng)編寫完成,在需要權(quán)限的地方調(diào)用 requestForPermissions 申請即可,代碼如下:

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

以上就是本篇文章的全部內(nèi)容,如有問題歡迎指出,我們一起進(jìn)步。
如果喜歡的話希望點(diǎn)個(gè)贊吧,您的鼓勵(lì)是我前進(jìn)的動(dòng)力。
謝謝~~

項(xiàng)目地址

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容