在 Android 6.0 以上版本中,Android 應用程式權限模式的設計目的是讓使用者更容易瞭解權限、發揮權限的效用,並確保權限的安全性。這個模型將需要危險權限的 Android 應用程式 (請參閱「受影響的權限」) 從安裝時間權限模型移至執行階段權限模型:
- 安裝期間權限
(Android 5.1 以下版本) 使用者在安裝或更新應用程式時,會向應用程式授予危險權限。裝置製造商和電信業者可以預先安裝已預先授予權限的應用程式,而無須通知使用者。
- 執行階段權限
(Android 6.0 到 9) 使用者在應用程式執行時授予危險權限。權限要求的時機 (例如應用程式啟動時或使用者存取特定功能時) 取決於應用程式,但使用者會授予/拒絕應用程式存取特定權限群組。原始設備製造商/電信業者可以預先安裝應用程式,但除非經過例外程序,否則無法預先授予權限。(請參閱「建立例外狀況」)。
(Android 10) 使用者可看到更透明的資訊,並可控管哪些應用程式擁有活動辨識 (AR) 執行階段權限。系統會透過 執行階段權限對話方塊提示使用者,要求他們選擇要一律允許、使用時允許或拒絕權限。在作業系統升級至 Android 10 後,系統會保留授予應用程式的權限,但使用者可以前往「設定」變更這些權限。
執行階段權限可防止應用程式在未經使用者同意的情況下取得私人資料存取權,並提供額外的背景資訊,讓使用者瞭解應用程式要求或已取得的權限類型。這個執行階段模型鼓勵開發人員協助使用者瞭解應用程式為何需要要求的權限,並提供更高的透明度,讓使用者能做出更明智的授予或拒絕權限決定。
受影響的權限
Android 6.0 以上版本需要危險權限才能使用執行階段權限模型。危險權限是風險較高的權限 (例如 READ_CALENDAR
),可讓要求權限的應用程式存取使用者私人資料,或控管裝置,可能對使用者造成負面影響。如要查看危險權限清單,請執行下列指令:
adb shell pm list permissions -g -d
Android 6.0 以上版本不會變更一般權限的行為。這些都是非危險權限,包括一般、系統和簽章權限。一般權限是風險較低的權限 (例如 SET_WALLPAPER
),可讓要求權限的應用程式存取隔離的應用程式層級功能,對其他應用程式、系統或使用者造成的風險最低。如同 Android 5.1 以下版本,系統會在安裝期間自動將一般權限授予要求的應用程式,且不會提示使用者核准。如需權限的詳細資訊,請參閱 <permission> 元素說明文件。
Android 10 中的硬性和軟性限制
除了危險性質之外,權限還可分為硬限制或軟限制。無論是哪種情況,都必須將受限權限加入許可清單。未加入允許清單的硬性限制與未加入允許清單的軟性限制的運作方式不同:
- (嚴格限制) 應用程式無法授予不在許可清單中的權限。
- (軟性限制) 未列入許可清單的應用程式會根據所要求的特定權限運作。請參閱所要求權限的公開說明文件,瞭解這項行為。
安裝應用程式時,安裝程式 (例如 Google Play 商店) 可能會選擇不將應用程式的受限制權限列入許可清單。權限受到平台限制,只有在應用程式符合平台政策的特殊條件時,才能授予權限。嚴格限制的權限類型包括簡訊和通話記錄權限。
允許清單會在安裝期間,以及
- 在 Android 9 升級至 10 的過程中已安裝應用程式。
- 預先授予權限或預先安裝應用程式。
- 已定義的角色必須具備權限,才能將權限加入許可清單。
- 安裝工具 (例如 Google Play 商店) 會將權限標示為許可清單。
使用者無法手動將權限加入許可清單。
需求條件
執行階段權限模式適用於所有應用程式,包括預先安裝的應用程式,以及在設定程序中傳送至裝置的應用程式。應用程式軟體需求包括:
- 執行階段權限模型必須在所有搭載 Android 6.0 以上版本的裝置上保持一致。這項規定由 Android Compatibility Test Suite (CTS) 測試強制執行。
- 應用程式必須在執行階段提示使用者授予應用程式權限。詳情請參閱「更新應用程式」。對於提供裝置基本功能的預設應用程式和處理常式,系統可能會授予有限的例外狀況。(例如,裝置預設的撥號應用程式可能會處理
ACTION_CALL
,並取得「電話」權限)。詳情請參閱「建立例外狀況」。 - 具有危險權限的預先載入應用程式必須指定 API 級別 23,並維持執行階段權限模型。也就是說,應用程式安裝期間的 UI 流程不得偏離 PermissionController 的 AOSP 實作,使用者可以撤銷預先安裝應用程式的危險權限等等。
- 無頭應用程式必須使用活動來要求權限,或與擁有必要權限的其他應用程式共用 UID。詳情請參閱無頭應用程式。
權限遷移
在 Android 5.x 上授予應用程式的權限會在更新至 Android 6.0 以上版本後繼續授予,但使用者隨時可以撤銷這些權限。
在 Android 9 至 10 的更新中,所有嚴格限制的權限都會列入許可清單。如要進一步瞭解如何實作前景/背景分割權限,請參閱「Android 10 隱私權異動」,並從「要求背景位置資訊」開始閱讀。
整合
整合 Android 6.0 以上版本的應用程式執行階段權限模式時,您必須更新預先安裝的應用程式,才能與新模式搭配運作。您也可以為核心功能的預設處理常式/提供者應用程式定義例外狀況、定義自訂權限,以及自訂 PermissionController
應用程式使用的主題。
更新應用程式
系統映像檔和預先安裝的應用程式不會自動預先授予權限。建議您與預先安裝應用程式開發人員 (原始設備製造商、電信業者和第三方) 合作,按照開發人員規範進行必要的應用程式修改。具體來說,您必須確保預先安裝的應用程式已經過修改,以免使用者撤銷權限時發生當機和其他問題。
預先安裝的應用程式
在 Android 9 以下版本中,使用危險權限的預先載入應用程式必須指定 API 級別 23 以上版本,並維持 Android 6.0 以上版本的 AOSP 權限模型。舉例來說,應用程式安裝期間的 UI 流程不得偏離 PermissionController
的 Android 開放原始碼計畫實作。使用者甚至可以撤銷預先安裝應用程式的危險權限。
在 Android 6.0 到 9 之間的版本中,部分權限是在安裝流程中授予。不過,從 10 版開始,安裝流程 (由 Package
Installer
應用程式執行) 與權限授予 (在 Permission Controller
應用程式中) 是不同的函式。
無頭應用程式
只有活動可以要求權限。服務無法直接要求權限。
- 在 Android 5.1 以下版本中,無頭應用程式可以在安裝時或在未使用活動的情況下預先安裝時要求權限。
- 在 Android 6.0 以上版本中,無頭應用程式必須使用下列任一方法要求權限:
- 新增活動來要求權限。(這是建議做法)。
- 將 UID 分享給具有必要權限的其他應用程式。只有在需要平台將多個 APK 視為單一應用程式時,才使用此方法。
目的是避免使用者因權限要求出現在無關的情況下而感到困惑。
自訂 PackageInstaller UI
如有需要,您可以更新 PackageInstaller 使用的預設裝置主題 (Theme.DeviceDefault.Settings
和 Theme.DeviceDefault.Light.Dialog.NoActionBar
),自訂權限 UI 主題。不過,由於一致性對應用程式開發人員而言至關重要,因此您無法自訂權限 UI 的顯示位置、位置和規則。
如要加入其他語言的字串,請將字串提交至 Android 開放原始碼計畫。
建立例外狀況
您可以使用 PackageManager 中的 DefaultPermissionGrantPolicy.java
類別,為核心 OS 功能的預設處理常式或提供者應用程式預先授予權限。例如:
ACTION_CALL (Dialer) Default Phone, Contacts, SMS, Microphone
SMS_DELIVER_ACTION (SMS/MMS) Default Phone, Contacts, SMS
定義自訂權限
您可以將自訂權限和群組定義為「一般」或「危險」,並將 OEM/電信業者專屬權限新增至現有權限群組,就像在 Android 5.x 以下版本中一樣。
在 Android 6.0 以上版本中,如果您新增危險權限,必須以與其他危險權限相同的方式處理 (在應用程式執行階段要求,且可供使用者撤銷)。具體違規事項如下:
- 您可以為目前的群組新增權限,但無法修改危險權限和危險權限群組的 AOSP 對應項目。換句話說,您無法從群組移除權限,然後指派給另一個群組。
- 您可以在裝置上安裝的應用程式中新增權限群組,但無法在平台資訊清單中新增權限群組。
測試權限
Android 包含 Compatibility Test Suite (CTS) 測試,可驗證個別權限是否對應至正確的群組。通過這些測試是 Android 6.0 以上版本 CTS 相容性的必要條件。
撤銷權限
在 Android 13 以上版本中,您可以使用 Context.revokeSelfPermissionsOnKill()
撤銷自己授予的執行階段權限。撤銷作業會非同步進行,並在安全無虞且不會干擾使用者的情況下觸發。觸發撤銷時,系統會終止在呼叫 UID 中執行的所有程序。
請務必瞭解,撤銷單一權限可能不會反映在設定 UI 中,因為該 UI 會依群組處理權限。通常只要授予該群組中至少一項權限,系統就會顯示已授予權限群組。如果您希望使用者能夠在設定中確認權限撤銷,請務必撤銷權限群組中的所有權限。如要瞭解哪些權限屬於特定群組,您可以使用 PackageManager.getGroupOfPlatformPermission
和 PackageManager.getPlatformPermissionsForGroup
。
當系統撤銷要求的權限時,如果沒有授予對應的前景權限,系統也會撤銷對應的背景權限。
只要程序仍在前景執行,就不會觸發撤銷作業,但也可以立即觸發撤銷作業,方法是手動終止在目前 uid 中執行的所有程序,例如使用 System.exit()
。不過,建議您讓系統自行決定何時觸發。
權限撤銷生效後,您可以再次要求權限,系統會提示使用者核准或拒絕要求。您無法要求使用者先前拒絕的權限。雖然建議您撤銷目前持有但不再需要的權限,但請注意,您應在撤銷生效後,再向使用者告知撤銷一事。