在之前關於應用內數據本地保存為文件時,曾提到應用需要申請外部存儲設備的讀寫權限才能訪問外部存儲中的文件。那么針對某一種權限,應用程序具體應該怎么申請使用呢?本文將詳細介紹。
應用中的權限主要分為兩類,分為正常權限和危險權限。在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之前可參考上述方式。那么具體系統提供了哪些權限,獲得這些權限后可以做什么操作,這些問題將在后面的文章中介紹。