正確なアラームのスケジュールはデフォルトで拒否される

正確なアラームは、ユーザーの意図に基づく通知や、正確な時刻に実行する必要があるアクションに適しています。

SCHEDULE_EXACT_ALARM は、アプリで正確なアラームのスケジュールを設定できるように Android 12 で導入された権限です。この権限は、新しくインストールされた Android 13 以降をターゲットとするアプリのほとんどで、事前付与されなくなりました(デフォルトで拒否されます)。ユーザーがバックアップと復元の処理を介して Android 14 を搭載したデバイスにアプリデータを転送する場合でも、この権限は拒否されます。この権限が既存のアプリにすでに付与されている場合は、デバイスが Android 14 にアップグレードされたときにこの権限が事前付与されます。

次の API を介して正確なアラームを開始するには、SCHEDULE_EXACT_ALARM 権限が必要です。この権限がない場合、SecurityException がスローされます。

SCHEDULE_EXACT_ALARM 権限に関する既存のベスト プラクティスは、引き続き適用されます。

影響を受けるアプリ

Android 14 以降を搭載したデバイスの場合、この変更により、新しくインストールされた、次の特性を持つアプリが影響を受けます。

  • Android 13(API レベル 33)以降をターゲットとしている。
  • マニフェストで SCHEDULE_EXACT_ALARM 権限を宣言している。
  • 除外または事前付与のシナリオに該当しない。
  • カレンダー アプリやアラームアプリではない

カレンダー アプリとアラームアプリで USE_EXACT_ALARM を宣言する

カレンダー アプリやアラームアプリでは、アプリが実行されていないときに、カレンダーのリマインダー、アラーム、またはアラートを送信する必要があります。これらのアプリは、USE_EXACT_ALARM の標準の権限をリクエストできます。USE_EXACT_ALARM 権限はインストール時に付与されます。この権限を保持しているアプリは、SCHEDULE_EXACT_ALARM 権限を持つアプリと同様に正確なアラームのスケジュールを設定できます。

正確なアラームを必要としないユースケース

SCHEDULE_EXACT_ALARM 権限はデフォルトで拒否され、権限の付与プロセスでユーザーによる追加の手順が必要になるため、ユースケースを評価して、正確なアラームが本当に必要かどうかを判断することを強くおすすめします。

正確なアラームを必要としない一般的なワークフローを以下に示します。

アプリの全期間における繰り返し処理のスケジュール設定
set() メソッドは、タスクでリアルタイムの制約を考慮する必要がある場合に便利です(アラームを明日の午後 2 時に鳴らす、30 分後に鳴らす、など)。それ以外の場合は、代わりに postAtTime() メソッドまたは postDelayed() メソッドを使用することをおすすめします。
アプリの更新やログのアップロードなど、バックグラウンド処理のスケジュール設定
WorkManager を使用すると、タイミングが重要となる定期的な処理のスケジュールを設定できます。繰り返し間隔とフレックス間隔(15 分以上)を指定して、処理のランタイムを細かく定義できます。
システムがアイドル状態のときに、おおよその時間にアラームを鳴らす必要がある
不正確なアラームを使用します。具体的には、setAndAllowWhileIdle() を呼び出します。
特定の時間が経過した後に行う必要があるユーザー指定のアクション
不正確なアラームを使用します。具体的には、set() を呼び出します。
時間枠内で行われる可能性があるユーザー指定のアクション
不正確なアラームを使用します。具体的には、setWindow() を呼び出します。指定できる最短の時間枠は 10 分です。

正確なアラームを引き続き使用するための移行手順

アプリは正確なアラームのスケジュールを設定する前に、少なくとも権限があるかどうかを確認する必要があります。アプリが権限を持っていない場合は、インテントを呼び出して、ユーザーに権限をリクエストする必要があります。

これは、特別な権限をリクエストする標準のワークフローと同じです。

  1. アプリは AlarmManager.canScheduleExactAlarms() を呼び出して、適切な権限があることを確認する必要があります。
  2. アプリにその権限がない場合は、ACTION_REQUEST_SCHEDULE_EXACT_ALARM を含むインテントを呼び出し、アプリのパッケージ名を指定して、ユーザーに権限の付与を依頼します。

    アプリの onResume() メソッドでユーザーの判断を確認します。

  3. ユーザーが権限を付与した場合に送信される AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED ブロードキャストをリッスンします。

  4. ユーザーがアプリに権限を付与した場合、アプリは正確なアラームを設定できます。ユーザーが権限を拒否した場合は、アプリ エクスペリエンスのグレースフル デグラデーションを行って、その権限で保護される情報がなくてもユーザーに機能が提供されるようにします。

次のコード スニペットは、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 が事前に付与されます。

テストに関するガイドライン

この変更をテストするには、システム設定の [特別なアプリアクセス] ページからアプリの [アラームとリマインダー] 権限を無効にし([設定] > [アプリ] > [特別なアプリアクセス] > [アラームとリマインダー])、アプリの動作を確認します。