Android6.0運行時權限的處理及解決辦法

問題背景

隨着今年Android6.0系統的國產ROM終於來了,適配6.0已經勢在必行了。最近也有不少開發者在微信私聊和諮詢我遇到的問題,其中有一些都是關於Android6.0權限的,我感受有必要寫一篇文章來解惑了。Runtime Permissions在6.0系統的幾個變化中,仍是比較大的。程序員

若是你在Android6.0系統的手機上若是遇到了這樣的錯誤,一定跟其運行時權限有關。
open failed: EACCES (Permission denied)微信

權限變化

在Adroid系統6.0之前,權限的處理是在App安裝時受權,受權完了才能完成相關的安裝。而在6.0的系統上,是先安裝App,在安裝完以後,在使用相關權限的操做時,纔會彈出權限的提示框,用戶贊成受權以後才能正常使用。谷歌這樣作,可讓用戶更加清醒的認識相關權限的使用,在必定程度上更加人性化和保護了用戶的隱私。網絡

谷歌官方將權限分爲了兩類,一個是正常權限(Normal Permissions),這類權限不涉及用戶隱私,是不須要用戶進行受權的,好比訪問網絡,手機震動等。還有一類是危險權限(Dangerous Permissions),通常是涉及到用戶隱私的,須要用戶進行受權,好比操做SD卡的寫入,相機,錄音等。ide

Normal Permissions:

ACCESS_LOCATION_EXTRA_COMMANDS
ACCESS_NETWORK_STATE
ACCESS_NOTIFICATION_POLICY
ACCESS_WIFI_STATE
BLUETOOTH
BLUETOOTH_ADMIN
BROADCAST_STICKY
CHANGE_NETWORK_STATE
CHANGE_WIFI_MULTICAST_STATE
CHANGE_WIFI_STATE
DISABLE_KEYGUARD
EXPAND_STATUS_BAR
GET_PACKAGE_SIZE
INSTALL_SHORTCUT
INTERNET
KILL_BACKGROUND_PROCESSES
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_INSTALL_PACKAGES
SET_ALARM
SET_TIME_ZONE
SET_WALLPAPER
SET_WALLPAPER_HINTS
TRANSMIT_IR
UNINSTALL_SHORTCUT
USE_FINGERPRINT
VIBRATE
WAKE_LOCK
WRITE_SYNC_SETTINGSui

Dangerous Permissions:

解決方法

看完官方文檔,還好解決方案還不是太難,也不是很是麻煩,固然和之前相比仍是有一點繁瑣的。廢話很少說了,解決方案以下。spa

檢查系統版本

private boolean canMakeSmores(){

    return(Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP_MR1);

}

檢查系統版本的緣由,顯而易見,若是是系統6.0及以上的,須要採用新的權限受權方法。code

受權回調處理

@Override

public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){

    switch(permsRequestCode){

        case 200:

            boolean cameraAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED;
            if(cameraAccepted){
                //受權成功以後,調用系統相機進行拍照操做等
            }else{
                //用戶受權拒絕以後,友情提示一下就能夠了
            }

            break;

    }

}

進一步處理和完善

經過上面能夠看出,只檢查系統版本了,若是受權過的權限,還須要再次去受權麼?咱們的判斷其實能夠更完善一下,好比:orm

private boolean hasPermission(String permission){

    if(canMakeSmores()){

        return(checkSelfPermission(permission)==PackageManager.PERMISSION_GRANTED);

    }

    return true;

}

上面這段代碼,是先判斷系統版本,再判斷這個權限是否已經受權過,這樣就不會重複了。開發

還有就是好比若是用戶第一次已經拒絕過這個權限,下次再操做時怎麼辦呢?還有一個更人性化的方法就是:文檔

shouldShowRequestPermissionRationale(@NonNull String permission)

這個方法的做用:

  1. 第一次請求權限時,用戶拒絕了,下一次:shouldShowRequestPermissionRationale() 返回 true,應該顯示一些爲何須要這個權限的說明

  2. 第二次請求權限時,用戶拒絕了,並選擇了「不在提醒」的選項時:shouldShowRequestPermissionRationale() 返回 false

  3. 設備的策略禁止當前應用獲取這個權限的受權:shouldShowRequestPermissionRationale() 返回 false


 

文/非著名程序員(簡書做者) 原文連接:http://www.jianshu.com/p/8355bae8d302 著做權歸做者全部,轉載請聯繫做者得到受權,並標註「簡書做者」。

相關文章
相關標籤/搜索