Android系統編程入門系列之應用許可權的定義與申請

在之前關於應用內數據本地保存為文件時,曾提到應用需要申請外部存儲設備的讀寫許可權才能訪問外部存儲中的文件。那麼針對某一種許可權,應用程式具體應該怎麼申請使用呢?本文將詳細介紹。

應用中的許可權主要分為兩類,分為正常許可權和危險許可權。在Android6.0即API 23之前,這兩種許可權均只需要在清單文件中聲明即可,自Android6.0即API 23開始,危險許可權不僅需要在清單文件中聲明,還需要在程式碼使用該許可權的介面Activity中動態申請,彈出許可權申請框,由用戶決定是否授權。應用所需要的許可權列表及授權結果,可以從系統設置-應用管理-許可權管理中查看。

這裡對許可權的分類與官網許可權分類有所差異,為了便於理解,將官網的許可權等級與本文中的許可權分類對照關係繪製下表。

許可權等級ProtectionLevel 本文許可權分類
normal 正常許可權
signature 正常許可權
dangerous 危險許可權
appop 正常許可權

許可權的相關設置,大多是在清單文件中配置的,只有在動態申請或增加附加許可權與四大組件交互時需要在程式碼中配置。

如果應用程式如果需要使用某種許可權,就必須在其清單文件中聲明這些許可權。

在清單文件中使用標籤<uses-permission />,並為其屬性android:name賦值,不同的許可權分別定義了對應的字元串值。這些不同的許可權可以從android.Manifest.permission許可權類中查看。

從Android6.0即API 23開始,危險許可權需要動態申請,並由用戶主動授權後,才能繼續執行獲得授權後的操作,否則在未經授權時執行相關操作,程式運行時會拋出java.lang.SecurityException異常。

動態申請的許可權,同樣需要藉助Context上下文環境對象來完成授權的相關操作。同時由於Android系統庫的升級,下面涉及到的相關類,可以在老的系統支援庫android.support.v4中找到,同樣也可以在新版的androidx.core支援庫中找到對應類。

動態申請許可權,主要分為三個步驟,檢查、請求、結果回調。

檢查主要針對兩個方向,一是檢查應用程式是否已獲得相關許可權。調用ContextCompat.checkSelfPermission(Context context, String permission)靜態方法,將上下文環境對象和相關許可權的固定字元串分別作為參數傳入即可。返回int類型的結果標註是否授權,其數值在android.content.pm.PackageManager類中以靜態常量的形式分別定義了已授權的PERMISSION_GRANTED=0和未授權的PERMISSION_DENIED=-1。

如果檢查許可權結果是已授權,那麼可以執行獲得該許可權的後續操作。而當結果是未授權時,需要繼續檢查當前許可權是否可向用戶展示請求授權介面。調用ActivityCompat.shouldShowRequestPermissionRationale(android.app.Activity, java.lang.String)靜態方法,參數activity是當前所在Activity介面對象,參數permission是相關許可權字元串常量。返回boolean類型的結果,表示是否可正常展示請求授權介面。

如果檢查展示請求授權介面結果失敗,則需要提示用戶相關許可權無法正常授權,通常會提示用戶可以到系統設置-許可權管理中將該應用程式的相關許可權打開,以正常執行應用程式獲得授權後的操作。而當檢查展示介面返回結果是true時,可以繼續請求該許可權。調用ActivityCompat.requestPermissions(Activity activity, String[] permissions, int requestCode)靜態方法,參數activity是當前所在Activity介面對象,參數permissions是多個許可權字元串組成的數組,參數requestCode是當前請求值,可任意定義,同時該值與請求結果返回時對應一致。

這裡注意,在請求許可權時必須要傳入Activity介面對象,也就是說要想請求許可權,必須通過應用程式的某個已處於正常運行狀態的可視介面。而所謂的請求許可權,與介面之間的互相啟動有些相似,其本質都是一樣的。

最後是請求結果的回調,在請求許可權的Activity介面中,重寫方法public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults){}。在用戶選擇同意授權或拒絕授權後,由系統回調該方法。其中參數requestCode是請求值,與請求許可權時的參數一致;參數permissions是相關的許可權數組,同樣與請求許可權時的參數一致;參數grantResults是用戶的授權結果,其數組索引與參數permissions中的索引一一對應,取值同樣有表示已授權的PERMISSION_GRANTED=0和未授權的PERMISSION_DENIED=-1。

在請求結果返回的所有許可權均已授權後,邊可以執行獲得相關許可權的後續操作。如果有未授權的許可權,通常是執行異常操作,例如給用戶相應提示並不再執行正常的後續操作。

另外,在檢查許可權相關操作返回如果某項許可權在之前由用戶選擇拒絕授權並不再提示,


應用程式中對許可權的使用方式在Android12之前可參考上述方式。那麼具體系統提供了哪些許可權,獲得這些許可權後可以做什麼操作,這些問題將在後面的文章中介紹。