精確鬧鐘是針對使用者需求或需要在確切時間發生的操作所設計的通知。
Android 12 為應用程式推出的 SCHEDULE_EXACT_ALARM
權限可設定精確鬧鐘時間,而不再預先授予以 Android 13 為目標版本所安裝的最新應用程式 (依預設將設為拒絕)。如果使用者透過備份與還原作業,將應用程式資料轉移至執行 Android 14 的裝置,則權限仍會遭到拒絕。如果現有應用程式已具備這項權限,系統會在裝置升級至 Android 14 時預先授予權限。
您必須具備 SCHEDULE_EXACT_ALARM
權限,才能透過下列 API 啟動精確鬧鐘,否則系統將擲回 SecurityException
:
SCHEDULE_EXACT_ALARM
權限的現行最佳做法仍適用,其中包括:
- 在為精確鬧鐘排程之前,請先透過
canScheduleExactAlarms()
檢查權限。 - 設定您的應用程式,以便監聽使用者授予權限後,由系統所傳送的
AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED
前景廣播訊息,並做出適當回應。
受影響的應用程式
如果裝置執行 Android 14 或以上版本,則此將對具備下列特性的新安裝應用程式造成影響:
- 以 Android 13 (API 級別 33) 以上版本為目標版本。
- 在資訊清單中宣告
SCHEDULE_EXACT_ALARM
權限。 - 不屬於豁免或預先授權情境。
- 不是日曆或鬧鐘時鐘應用程式。
日曆和鬧鐘應用程式應宣告 USE_EXACT_ALARM
日曆或鬧鐘應用程式需要在應用程式停止運作時傳送行事曆提醒、起床鬧鐘或提醒。這些應用程式可以要求 USE_EXACT_ALARM
一般權限。安裝時將授予 USE_EXACT_ALARM
權限,而且擁有此權限的應用程式可以擁有 SCHEDULE_EXACT_ALARM
權限的應用程式一樣,為精確鬧鐘進行排程。
可能不需要精確鬧鐘的用途
由於根據預設,SCHEDULE_EXACT_ALARM
權限目前為遭拒狀態,而且需要使用者進行額外步驟才能授予權限,因此我們強烈建議開發人員評估用途,並確認其用途是否需要真的需要精確鬧鐘。
以下列出不需要精確鬧鐘的常見工作流程:
- 在應用程式的生命週期中安排週期性工作
- 如果工作需要記住即時限制 (例如:在明天下午 2 點或在 30 分鐘後結束),則
set()
是非常實用的方法。如果不是的話,請改用postAtTime()
或postDelayed()
方法。 - 排定的背景作業,例如:更新應用程式和上傳記錄檔
WorkManager
可讓您安排具時效性的定期工作。 您可以提供重複間隔和彈性間隔 (至少 15 分鐘),藉此定義精細的工作執行時間。- 當系統處於閒置狀態時,需要鬧鐘在約略時間過後響起
- 請使用非精準鬧鐘。具體來說,請呼叫
setAndAllowWhileIdle()
。 - 在特定時間後所應採取的使用者指定動作
- 請使用非精準鬧鐘。具體來說,請呼叫
set()
。 - 指定時限內可以進行的使用者指定動作
- 請使用非精準鬧鐘。具體來說,請呼叫
setWindow()
。請注意,系統允許的最小時間間隔為 10 分鐘。
繼續使用精確鬧鐘的遷移步驟
應用程式至少必須先檢查是否有權限,才能設定精確鬧鐘。如果應用程式不具備權限,便必須透過叫用意圖的方式,向使用者要求權限。
這和要求特殊權限的標準工作流程相同:
- 應用程式應呼叫
AlarmManager.canScheduleExactAlarms()
,確認其具備適當權限。 如果應用程式未具備權限,請叫用含有
ACTION_REQUEST_SCHEDULE_EXACT_ALARM
的意圖以及應用程式的套件名稱,以便要求使用者授予權限。在應用程式的
onResume()
方法中,查看使用者的決定。監聽使用者授予權限時所傳送的
AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED
廣播訊息。如果使用者已授予應用程式權限,則應用程式便可設定精確鬧鐘。如果使用者拒絕權限要求,請為應用程式體驗進行優雅降級,這樣一來,即使沒有受到該項權限保護的相關資訊,應用程式也能為使用者執行功能。
下列程式碼片段說明如何檢查 SCHEDULE_EXACT_ALARM
權限:
val alarmManager: AlarmManager = context.getSystemService<AlarmManager>()!!
when {
// If permission is granted, proceed with scheduling exact alarms.
alarmManager.canScheduleExactAlarms() -> {
alarmManager.setExact(...)
}
else -> {
// Ask users to go to exact alarm page in system settings.
startActivity(Intent(ACTION_REQUEST_SCHEDULE_EXACT_ALARM))
}
}
用於查看權限並處理使用者 onResume()
決定的程式碼範例:
override fun onResume() {
…
if (alarmManager.canScheduleExactAlarms()) {
// Set exact alarms.
alarmManager.setExact(...)
}
else {
// Permission not yet approved. Display user notice and revert to a fallback
// approach.
alarmManager.setWindow(...)
}
}
權限遭拒的優雅降級
部分使用者會拒絕授予權限。在此情況下,建議以優雅的方式降級應用程式體驗,同時透過識別用途,盡可能提供最佳的備用使用者體驗。
豁免資格
下列類型的應用程式一律可以呼叫 setExact()
或 setExactAndAllowWhileIdle()
方法:
- 使用平台憑證簽署的應用程式。
- 具備特殊權限的應用程式。
- 列入電源許可清單的應用程式 (如果您的應用程式符合相關規定,便可使用
ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
意圖動作要求權限)。
預先授權
SYSTEM_WELLBEING
的角色持有者將預先獲得SCHEDULE_EXACT_ALARM
權限。
測試規範
如要測試這項變更,請從系統設定的「特殊應用程式存取權」頁面,停用應用程式的「鬧鐘與提醒」權限 (設定 > 應用程式 > 特殊應用程式存取權 > 鬧鐘與提醒),然後觀察應用程式的行為是否有所改變。