Android6.0權限管理以及使用權限該注意的地方


Android 6.0 Marshmallow首次增加了執行時權限管理,這對用戶來說,能夠更好的了解、控 制 app 涉及到的權限。然而對開發人員來說卻是一件比較蛋疼的事情。須要兼容適配,並保證程序功能的正常執行。
什么叫執行時權限管理呢?在Android 6.0以下的系統中,當我們在安裝應用的時候,該應用就會提示我們這個應用所須要的權限,假設你要安裝。那就必須允許賦予全部權限,可是假設不允許,那就僅僅能取消安裝了,有點流氓。並且安裝完后,你不能夠收回這個權限。
而6.0就做到了執行時權限管理。即使安裝的時候給了權限,也能夠到系統設置里。去關閉該權限。
以下分幾種情況來講,由於執行時權限僅僅有在Android6.0及以上的手機版本號才有,所以這里僅僅考慮設備版本號大於6.0的手機。低版本號的手機在安裝時就已經賦予了全部的權限。也不可能收回,就不考慮了,以下的情況僅僅分targetSdkVersion:

  1. targetSDKVersion大於等於23的時候,那么權限是能夠被回收(revoke)。這里還要分權限。google將權限分為兩種,一種是normal permission,還有一種是dangerous permission。

    normal permission是指與用戶隱私無關的權限。能夠理解為無關緊要的權限,比方說訪問網絡的權限。對用戶來說沒什么關系。dangerous permission就是會涉及到用戶隱私的權限。比如讀取用戶手機聯系人、短信等等。假設是normal permission的話,那么在安裝的時候就會給,並且不會開放接口讓用戶回收該權限。app會一直擁有該權限,所以不用考慮這樣的類型的權限。假設是dangerous permission的話,在安裝的時候並未授予權限。系統開放接口允許用戶回收或者賦予權限。以下是某個應用的權限,第一張圖是dangerous permission。能夠回收和賦予的。


    這里寫圖片描寫敘述
    點擊上面的全部權限,能夠查看到該應用全部的權限。
    這是全部的權限,包含normal and dangerous
    那么對於dangerous permission的話,在使用前須要去檢查該permission是否已經被授予

checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED

假設該權限已經被授予,那么可繼續執行你的代碼,假設未授予,則須要向用戶詢問是否須要授予權限。彈出的框是系統界面,界面例如以下:
這里寫圖片描寫敘述
調用代碼:

requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE}, 1);

系統詢問是否授予權限的頁面結束后會有回調

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
   super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 1) {
        if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
            //your implementations
        }else{
            ToastUtil.show(this, "權限不足。支付失敗");
        }
    }
}
  1. 假設targetSdkVersion是小於23的。那么將覺得app沒實用23新權限測試過,那么繼續使用老規則:系統在安裝的時候會默認給app賦予全部的權限,app能夠照常執行。可是!可是!可是!

    用戶依舊能夠回收權限,只是此回收非彼回收。先看下關閉權限時彈的頁面:
    這里寫圖片描寫敘述
    看到了么。假設targetSDKVersion小於23的話,在關閉權限的時候。會彈一個警告框,告訴你這是舊版的android,關閉會有問題,假設你按拒絕。那么該權限將會關閉。並且界面上。權限的開關會顯示關。可是這個權限卻沒有被回收(nexus 5x的手機親測。當然其它的機子我也不敢打包票)。checkSelfPermission返回granted。我看了下。假設targetSDKVersion等於23的話。系統日志是:
    這里寫圖片描寫敘述
    假設targetSDKVersion是小於23的話,則日志是:
    Permission related app op changed.

只是我猜想假設你要支持runtime permission的話,還是要把targetSDKVersion設為23。假設你的targetSDKVersion是小於23的話,那么還是要加上checkSelfPermission,以防萬一。誰知道google會出什么坑。

還有就是權限的話,有分組的概念,看例如以下圖:
這里寫圖片描寫敘述
假設一組中有一個被授予了,那么組內的也會默認被授予。

並且也支持同一時候申請多個權限,詳細情況android developer官網。

以下是stackoverflow問題的網址:
http://stackoverflow.com/questions/36328151/ive-revoke-the-android-permission-but-checkselfpermission-still-return-granted

如有問題和錯誤的地方請指出。

以下就是要講一些權限管理注意的地方。
對於權限的話,Activity和Fragment都有自己的requestPermissions和onRequestPermissionsResult回調,可是Activity是有checkSelfPermission。可是fragment是沒有的,所以fragment假設想要檢查權限,還得調用宿主activity的checkSelfPermission。
對了,平時直接調用checkSelfPermission和requestPermissions會報什么api錯誤,盡管編譯不會通過,可是看着就是煩啊。能夠調用ActivityCompat.checkSelfPermission(在supportv4包中)。
先看下Activity的requestSelfPermission這種方法:

public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
    Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
    startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);
}

看下這里是直接打開還有一個Activity進行操作,還用了startActivityForResult,回調會通過onRequestPermissionResult,我想這個回調應該是在onActivityResult里面處理。然后調這個onRequestPermissionResult函數的。
那么問題來了,假設我在onResume函數中申請某一個權限,調用requestPermissions,那么現象是什么樣的呢?
第一次進入頁面,彈出申請權限的對話框,假設點擊允許。則正常,對話框不會再顯示。可是假設第一次點擊拒絕,則點擊拒絕后重新彈出對話框來申請權限,假設你一直點拒絕。則對話框一直彈出,這是為什么呢?由於第一次進入頁面並執行onResume函數時申請權限,進入還有一個頁面。彈出對話框,假設你點擊拒絕。先是回調onRequestPermissionResult,然后再執行onResume函數,這時又會再一次去檢查權限,由於發現無權限,則再一次請求,如是,進入一個循環之中,除非你點允許,否則是個無限循環。

所以申請權限不妨不要寫在onResume中,或者加一個標志位推斷。


接下來再講講Fragment請求權限。

public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
    if (mHost == null) {
        throw new IllegalStateException("Fragment " + this + " not attached to Activity");
    }
    mHost.onRequestPermissionsFromFragment(this, permissions,requestCode);
}

這里看到事實上是調用mHost請求權限的方法。mHost就是這個fragment的宿主Activity,所以Fragment請求權限實際上也是通過宿主Activity,當權限結果回調時,activity推斷是從Fragment中來的還是從自己Activity中來的,再進行分發結果。

Github上也有一些比較好用的權限庫:https://github.com/hotchemi/PermissionsDispatcher


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM