バックグラウンドからのアクティビティの起動に関する制限

Android 10(API レベル 29)以降では、アプリがバックグラウンドで実行されているときに アクティビティを開始できるタイミングが制限されています。これらの制限により、ユーザーに対する割り込みを最小限に抑え、ユーザーは画面内の表示内容を詳細に制御できるようになります。

このガイドでは、バックグラウンドからのアクティビティ起動に代わる手段として通知を紹介します。また、制限が適用されない具体的なケースも記載されています。

代わりに通知を表示する

通常の場合、バックグラウンドにあるアプリは、直接アクティビティを起動するのではなく、タイミングが重要な通知を表示してユーザーに緊急の情報を提供する必要があります。このような通知には、着信電話やアラームの処理が含まれます。

この通知ベースのアラート / リマインダー システムは、ユーザーにとってさまざまなメリットがあります。

  • デバイスを使用している最中でも、ヘッドアップ通知が表示されるため、返信することができます。ユーザーは現在のコンテキストを維持しつつ、画面に表示されるコンテンツを制御できます。
  • 緊急性の高い通知には、ユーザーの [サイレント モード] ルールが適用されます。たとえば、[サイレント モード] が有効になっている場合、ユーザーは、特定の連絡先からの通話や同一発信者による再発信だけを許可することができます。
  • デバイスの画面がオフになると、すぐに全画面表示インテントが起動されます。
  • デバイスの [設定] 画面で、最近通知を送信したアプリや使用された通知チャネルを確認できます。この画面から、ユーザーは自分の通知設定を制御できます。

アプリがアクティビティを開始できるタイミング

Android 10 以降で稼働するアプリは、以下の 1 つまたは複数の条件が満たされた場合に限り、アクティビティを起動できます。

  • フォアグラウンドにあるアクティビティなど、アプリが可視ウィンドウを持っている場合。
  • フォアグラウンド タスクのバックスタック内に、アプリのアクティビティがある場合。
  • アプリのアクティビティが、履歴画面の既存タスクのバックスタックにある。

  • アプリが、ごく最近起動されたアクティビティを持っている場合。

  • アプリがごく最近アクティビティの finish() を呼び出した場合。この条件が適用されるのは、finish() の呼び出し時に、アプリがフォアグラウンド内にアクティビティを持っていた場合か、フォアグラウンド タスクのバックスタック内にアクティビティを持っていた場合に限られます。

  • アプリが、システムによってバインドされている次のいずれかのサービスを持っている場合。これらのサービスは UI を起動する必要がある場合があります。

  • アプリが、別の可視アプリによってバインドされているサービスを持っている場合。アクティビティを正常に起動するためには、サービスにバインドされているアプリが、バックグラウンド内で対象アプリに対して可視状態を維持している必要があります。

  • アプリが PendingIntent 通知をシステムから受信した場合。サービスやブロードキャスト レシーバを対象とするペンディング インテントの場合、アプリは、ペンディング インテントが送信された後、数秒間アクティビティを起動できます。

  • アプリが、別の可視アプリから送信された PendingIntent を受信した場合。

  • アプリが、UI を起動することが想定されるシステム ブロードキャストを受信する。ACTION_NEW_OUTGOING_CALLSECRET_CODE_ACTION などがあります。アプリはブロードキャストが送信された後、数秒間アクティビティを起動できます。

  • アプリが CompanionDeviceManager API 経由でコンパニオン ハードウェア デバイスに関連付けられている場合。この API により、アプリはペア設定されたデバイス上でユーザーが実行するアクションに応じてアクティビティを起動できます。

  • アプリが、デバイス オーナー モードで稼働しているデバイス ポリシー コントローラの場合。ユースケースの例としては、完全管理型エンタープライズ デバイスや、デジタル サイネージ、キオスクなどの専用デバイスがあります。

  • ユーザーがアプリに SYSTEM_ALERT_WINDOW 権限を付与している。

PendingIntent からアクティビティを開始する場合はオプトインが必要

記載の条件に基づいてアクティビティが誤って開始されるのを防ぐため、Android 14 以降では、アクティビティの開始権限をアプリに付与するかどうかを明示的に選択できる API が用意されています。

Android 15 以降をターゲットとするアプリは、デフォルトで、作成した PendingIntents にバックグラウンド アクティビティ起動(BAL)権限を暗黙的に付与しなくなります。明示的なオプトインが必要です。アプリが PendingIntents を送信または作成しているかどうかに応じて、次のオプションがあります。

ペンディング インテントの表
図 1: バックグラウンド アクティビティの起動に関する決定フロー。

PendingIntent の送信者による

Android 14 以降をターゲットとし、PendingIntent を開始したいアプリは、

  • 記載されている条件をすべて満たしている
  • これらの例外に基づいてバックグラウンド アクティビティの起動を許可するようオプトインする

このオプトインは、アプリがアクティビティを開始することをアプリ デベロッパーが認識している場合にのみ発生します。

オプトインするには、アプリで setPendingIntentBackgroundActivityStartMode(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED) を含む ActivityOptions バンドルを PendingIntent.send() などのメソッドに渡す必要があります。

PendingIntent の作成者による

Android 15 以上をターゲットとし、PendingIntent を作成するアプリは、リストに記載された条件PendingIntents を起動可能にする場合、バックグラウンド アクティビティの起動を許可するために明示的にオプトインする必要があります。

ほとんどの場合、PendingIntent を開始するアプリがオプトインする必要があります。ただし、作成側のアプリがこれらの権限を付与する必要がある場合は、

  • PendingIntent は、作成アプリが表示されているときはいつでも開始できます。
  • 作成アプリに特別な権限がある場合、PendingIntent はいつでも開始できます。

オプトインするには、アプリで setPendingIntentCreatorBackgroundActivityStartMode (ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED) を含む ActivityOptions バンドルを PendingIntent.getActivity() などのメソッドに渡す必要があります。

詳細については、関連するリファレンス ドキュメントをご覧ください。

厳格モード

Android 16 以降では、アプリ デベロッパーは厳格モードを有効にして、アクティビティの起動がブロックされたとき(またはアプリのターゲット SDK が引き上げられたときにブロックされる可能性があるとき)に通知を受け取ることができます。

Application、Activity、その他のアプリ コンポーネントの Application.onCreate() メソッドの早い段階で有効にするコード例:

 override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     StrictMode.setVmPolicy(
         StrictMode.VmPolicy.Builder()
         .detectBlockedBackgroundActivityLaunch()
         .penaltyLog()
         .build());
     )
 }

詳しくは、厳格モードのドキュメントをご覧ください。