Android6.0極其以上系統(tǒng)獲取Dangerous系統(tǒng)權(quán)限問題及其解決方案

這是之前在CSDN上寫的一篇文章,發(fā)現(xiàn)最近又用到了,于是乎,就找出來并遷到簡書上了。
原地址:http://blog.csdn.net/abcdefkiller/article/details/49784125
開發(fā)過程當(dāng)中遇到一個(gè)問題,就是好好的app在Android6.0系統(tǒng)的五兒子里進(jìn)去就閃退,看了一下logcat表明時(shí)WRITE_EXTERNAL_STORAGE權(quán)限獲取不到造成的,but在AndroidManifest文件當(dāng)中已經(jīng)添加了該權(quán)限,只能猜測在6.0的機(jī)子上無法使用配置文件中的權(quán)限了,于是去setting里面把a(bǔ)pplication的權(quán)限手動(dòng)開啟試了一下,app就正常了。因此去趴了Android的官方文檔,https://developer.android.com/intl/zh-cn/training/permissions/requesting.html。
原來,系統(tǒng)升上6.0以后一些dangerous級(jí)別的權(quán)限已經(jīng)無法在app安裝時(shí)授權(quán)了,需要用戶在使用過程中碰到了由用戶主動(dòng)授權(quán)才行。

Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. This approach streamlines the app install process, since the user does not need to grant permissions when they install or update the app.

在系統(tǒng)權(quán)限當(dāng)中,分為normal和dangerous兩個(gè)級(jí)別,可以簡單理解為不獲取隱私的權(quán)限,如INTERNET、VIBRATE等權(quán)限為normal級(jí)別的,這些只需在AndroidManifest文件里設(shè)置就OK了,但涉及到用戶隱私如相機(jī)CAMERA、文件存儲(chǔ)WRITE_EXTERNAL_STORAGE、地理位置LOCATION等dangerous級(jí)別時(shí),在6.0系統(tǒng)時(shí)就無法直接設(shè)置了。具體兩個(gè)類別的系統(tǒng)權(quán)限可以參考:https://developer.android.com/intl/zh-cn/guide/topics/security/permissions.html#normal-dangerous Anyway要在marshmallow中使用dangerous權(quán)限需要在代碼中進(jìn)行實(shí)現(xiàn)。
首先,當(dāng)然是判斷工程中是否有用到dangerous級(jí)別的系統(tǒng)權(quán)限。

/**
     * 檢測是否申請(qǐng)了用戶權(quán)限
     * @param context 當(dāng)前頁面
     * @param permission 需要獲取的權(quán)限
     * @return boolean
     */
    public static boolean isPermissionAllowed(Context context, String permission) {
        return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
    }

該方法直接調(diào)用ContextCompat類去自檢工程中是否有permission,并與PackageManager.PERMISSION_GRANTED參數(shù)進(jìn)行比較返回一個(gè)boolean值,當(dāng)返回true時(shí),接下去邏輯代碼該怎么寫就怎么寫,當(dāng)false時(shí),一種選擇是自己定義沒有權(quán)限時(shí)的后續(xù)行為,但這不怎么科學(xué),為什么不使用6.0自帶的提示框呢,只要一行代碼就可以調(diào)用咯!

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_CAMERA_AUTHORITY);

于是代碼基本上是這么搞的:

if (PermissionUtils.isPermissionAllowed(this, Manifest.permission.CAMERA)) {

            ...// do what you want
            
} else {
    // 開啟系統(tǒng)默認(rèn)的權(quán)限獲取提示框
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_CAMERA_AUTHORITY);
        }

還沒完,如果開發(fā)者還需要對(duì)用戶點(diǎn)擊系統(tǒng)權(quán)限授權(quán)彈出框(見圖,長這樣子)后


request_permission_dialog.png

的后續(xù)行為進(jìn)行定義Android也提供了相關(guān)的回調(diào)方法。BTW該回調(diào)方法需要繼承FragmentActivity才有(因?yàn)樗械姆椒ǘ荚趘4包當(dāng)中),Activity是沒有的。調(diào)用的方法如下:

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case REQUEST_CODE_CAMERA_AUTHORITY: {
            // 如果用戶不授權(quán),grantResults就會(huì)是空的
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // 用戶授權(quán)了,你想怎么玩兒?

            } else {

                // 用戶不爽不授權(quán),執(zhí)行B計(jì)劃
            }
            return;
        }

        // switch case 語句用來區(qū)分同一界面的不同系統(tǒng)權(quán)限的操作
    }
}

以上!
對(duì)了,Tips: 保持Gradle里面v4包的版本一直最新吧,之前用了22版本的死活出不了這些方法,更新成最新的版本才可以調(diào)用這些代碼。

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

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

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