android6.0動態權限申請的正確流程

前言

從 Android 6.0(API 級別 23)開始,用戶開始在應用運行時向其授予權限,而不是在應用安裝時授予。因此若是你的應用使用到了一些危險權限,就必須在AndroidManifest.xml 中靜態地聲明須要用到的權限,並在使用到該功能時要動態的申請,不然在調用到相應權限功能時候,會拋出 SecurityException異常。因此本文探討一下動態權限的申請的正確流程,並把它封裝成一個庫,簡化了申請過程。java

權限的分類

在講解以前,先看一下android權限的分類,android權限分爲四類,以下:android

一、普通權限

普通權限也叫正常權限,它不須要動態申請,你只須要在用到它的時候在AndroidManifest.xml 中靜態地聲明,而後系統在app運行時就會自動的授予該app相應的權限。這類權限主要在你的app想要接觸app沙盒外的數據或資源的時用到,它不會涉及到系統的操做,也不會泄漏或篡改用戶的隱私數據。以下:git

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 
FOREGROUND_SERVICE 
GET_PACKAGE_SIZE 
INSTALL_SHORTCUT 
INTERNET 
KILL_BACKGROUND_PROCESSES 
MANAGE_OWN_CALLS 
MODIFY_AUDIO_SETTINGS 
NFC 
READ_SYNC_SETTINGS 
READ_SYNC_STATS 
RECEIVE_BOOT_COMPLETED 
REORDER_TASKS 
REQUEST_COMPANION_RUN_IN_BACKGROUND 
REQUEST_COMPANION_USE_DATA_IN_BACKGROUND 
REQUEST_DELETE_PACKAGES 
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 
SET_ALARM 
SET_WALLPAPER 
SET_WALLPAPER_HINTS 
TRANSMIT_IR 
USE_FINGERPRINT 
VIBRATE 
WAKE_LOCK 
WRITE_SYNC_SETTINGS 
複製代碼

二、簽名權限

該類權限只對擁有相同簽名的應用開放。例如某個應用自定義了一個permission 且在權限標籤中加入 android:protectionLevel=」signature」,其餘應用想要訪問該應用中的某些數據時,必需要在AndroidManifest.xml中聲明該權限,並且還要與該應用具備相同的簽名,系統會在app運行時自動授予該權限。這類咱們用的比較少。github

三、危險權限

也叫敏感權限,運行時權限,跟普通權限相反,一旦某個應該獲取了該類權限,用戶的隱私數據就面臨被泄露篡改的風險。因此你想使用該權限就必須在AndroidManifest.xml 中靜態地聲明須要用到的權限,並在使用到該功能時要動態的申請,除非用戶贊成該權限,不然你不能使用該權限對應的功能。以下:app

能夠看到android把危險權限分爲10組,因此申請危險權限的時候都是按組申請,咱們只要申請組內的任意一個危險權限就行,當用戶一旦贊成受權該危險權限,那麼該權限所對應的權限組中的全部其餘權限也會同時被受權。ide

四、特殊權限

特殊權限我瞭解的有三個,以下:測試

  • SYSTEM_ALERT_WINDOW:設置懸浮窗
  • WRITE_SETTINGS:修改系統設置
  • REQUEST_INSTALL_PACKAGES: 容許應用安裝未知來源應用

它也是要要申請的,可是它不一樣於危險權限的申請,危險權限的申請會彈出一個對話框詢問你是否贊成,而特殊權限的申請須要跳轉到指定的界面,讓你手動確認贊成。ui

動態權限申請流程

因此動態權限的申請就是申請危險權限或特殊權限,權限的申請在不一樣的Android版本有不一樣的行爲,以下:this

  • 若是設備運行的是 Android 5.1 或更低版本,或者應用的 targetSdkVersion 爲 22 或更低:若是您在 Manifest 中列出了危險權限,則用戶必須在安裝應用時系統會要求用戶授予此權限,若是他們不授予此權限,系統根本不會安裝應用,用戶一旦所有贊成授予,他們撤銷權限的惟一方式是卸載應用。
  • 若是設備運行的是 Android 6.0 或更高版本,而且應用的 targetSdkVersion爲23 或更高:應用必須在 Manifest 中列出權限,而且它必須在運行時請求其須要的每項危險權限。用戶能夠授予或拒絕每項權限,且即便用戶拒絕權限請求,應用仍能夠繼續運行有限的功能。用戶能夠隨時進入應用的「Settings」中調整應用的動態權限受權。因此你每次使用到該權限的功能時,都要動態申請,由於用戶有可能在「Settings」界面中把它再次關閉掉。

我這裏討論的是6.0後的動態申請,因此從 Android 6.0開始,不管您的應用面向哪一個 API 級別,您都應對應用進行測試,以驗證它在缺乏須要的權限時行爲是否正常。google

若是還不瞭解動態權限申請的詳細步驟,能夠看一下這篇文章:Android 6.0運行權限解析(高級篇)。

這裏我假設你們已經知道那些方法了,我把權限申請的流程分爲單個和多個權限申請,分別畫了個圖。

一、單個權限申請流程

二、多個權限申請流程

三、自定義提示權限組的提示框

上面兩個圖有有提到自定義提示權限組,那麼它主要包含如下內容:

  • 一、包含須要受權的權限列表或單個權限提示
  • 二、包含跳轉到應用設置受權界面中的跳轉按鈕
  • 三、包含放棄受權的取消按鈕,即取消這個提示框

注意:若是用戶不受權,則不能使用該功能或應用沒法運行,能夠考慮取消第3步的取消按鈕,即沒法取消這個提示框,必定要用戶去「Settings」受權。

其餘注意點

除了特殊權限外,還有一個location權限也比較特殊,須要經過 **LocationManager的isProviderEnabled(LocationManager.GPS_PROVIDER)**判斷是否打開定位開關後再進行權限申請,以下:

lm = (LocationManager) this.getSystemService(this.LOCATION_SERVICE);
    if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {//開了定位服務
        //請求定位功能
       PermissionHelper.getInstance().with(this).requestPermission(
                Manifest.permission.ACCESS_FINE_LOCATION,
                new IPermissionCallback() {
                    @Override
                    public void onAccepted(Permission permission) {
                        //...
                    }

                    @Override
                    public void onDenied(Permission permission) {
						//...
                    }
                }
        );
    } else {
        //跳轉到開啓定位的地方
        Toast.makeText(this, "系統檢測到未開啓GPS定位服務,請開啓", Toast.LENGTH_SHORT).show();
        Intent intent = new Intent();
        intent.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
        startActivityForResult(intent, PRIVATE_CODE);
    }
}
複製代碼

結語

本文主要讓讓你們對權限的申請流程有進一步的認識,而後能夠經過對動態權限的封裝,將檢測動態權限,請求動態權限,權限設置跳轉,監聽權限設置結果等處理和業務功能隔離開來,業務之後能夠很是快速的接入動態權限支持,提升開發效率,更多細節查看PermissionHelper

參考資料:

Permissions

相關文章
相關標籤/搜索