Android 10(API レベル 29)以降では、アプリがバックグラウンドで実行されているときにアプリがアクティビティを起動できるタイミングに制限が設けられています。この制限により、ユーザーへの中断を最小限に抑え、画面に表示される内容をユーザーがより細かく制御できるようになります。
このガイドでは、バックグラウンドからアクティビティを起動する代替手段として通知を紹介します。また、制限が適用されない具体的なケースも示します。
代わりに通知を表示する
通常の場合、バックグラウンドにあるアプリは、 タイミングが重要な通知を表示して、 直接アクティビティを起動するのではなく、緊急の情報をユーザーに提供する必要があります。 このような通知には、着信電話への対応や、アラーム時計の作動などが含まれます。
通知ベースのアラートとリマインダー システムには、ユーザーにとって次のようなメリットがあります。
- デバイスを使用している最中でも、ヘッドアップ通知が表示されるため、対応できます。ユーザーは現在のコンテキストを維持しつつ、画面に表示されるコンテンツを制御できます。
- タイミングが重要な通知には、ユーザーの [サイレント モード] ルールが適用されます。たとえば、[サイレント モード] が有効になっている場合、特定の連絡先からの通話や、繰り返し電話をかけてくる相手からの通話のみを許可できます。
- デバイスの画面がオフになると、すぐに全画面インテントが起動されます。
- デバイスの 設定 画面で、ユーザーは最近通知を送信したアプリや、特定の通知チャンネルからの通知を確認できます。この画面から、ユーザーは自分の通知設定を制御できます。
アプリがアクティビティを起動できる場合
Android 10 以降で実行されているアプリは、次のいずれかの条件を満たす場合にアクティビティを起動できます。
フォアグラウンドにあるアクティビティなど、アプリが可視ウィンドウを持っている場合。
フォアグラウンド タスクの バックスタック内に、アプリのアクティビティがある場合。
アプリのアクティビティが [最近] 画面の既存タスクのバックスタックにある場合。
アプリに、ごく最近起動したアクティビティがある場合。
アプリがごく最近アクティビティで
finish()を呼び出した場合。この条件が適用されるのは、finish()の呼び出し時に、アプリがフォアグラウンド内にアクティビティを持っていた場合か、フォアグラウンド タスクのバックスタック内にアクティビティを持っていた場合に限られます。アプリに、システムによってバインドされている次のいずれかのサービスがある場合。これらのサービスは、UI を起動する必要がある場合があります。
AccessibilityServiceAutofillServiceCallRedirectionServiceHostApduServiceInCallServiceTileService(Android 14(API レベル 34)以降では適用されません)VoiceInteractionServiceVrListenerService。
アプリが、別の可視アプリによってバインドされているサービスを持っている場合。アクティビティを正常に起動するためには、サービスにバインドされているアプリが、バックグラウンド内で対象アプリに対して可視状態を維持している必要があります。
アプリがシステムから通知
PendingIntentをシステムから受信する場合。サービスやブロードキャスト レシーバを対象とするペンディング インテントの場合、アプリは、ペンディング インテントが送信された後、数秒間アクティビティを起動できます。アプリが、別の可視アプリから送信された
PendingIntentを受信する場合。アプリが、アプリが UI を起動するシステム ブロードキャストを受信する場合。例としては、
ACTION_NEW_OUTGOING_CALLやSECRET_CODE_ACTIONがあります。 アプリはブロードキャストが送信された後、数秒間アクティビティを起動できます。アプリが
CompanionDeviceManagerAPI 経由でコンパニオン ハードウェア デバイスに関連付けられている場合。この API により、アプリはペア設定したデバイス上でユーザーが実行するアクションに応じてアクティビティを起動できます。アプリが、Device Policy Controllerが デバイス所有者モードで稼働している場合。ユースケースの例としては、 フルマネージド エンタープライズ デバイス や、デジタル サイネージ、キオスクなどの専用デバイスがあります。
アプリに、ユーザーによって
SYSTEM_ALERT_WINDOW権限が付与されている場合。
PendingIntent からアクティビティを起動する場合はオプトインが必要
Android 14 以降では、記載されている 条件に基づいてアクティビティが誤って起動されるのを防ぐため、アプリにアクティビティの起動権限を付与するかどうかをオプトインまたはオプトアウトできる明示的な API が用意されています。
Android 15 以降をターゲットとするアプリでは、作成した PendingIntents にバックグラウンド アクティビティ起動(BAL)権限が暗黙的に付与されなくなります。これを行うには明示的なオプトインが必要です。アプリが PendingIntents を送信しているか作成しているかに応じて、次のオプションがあります。
PendingIntent の送信者による
PendingIntent を起動する Android 14 以降をターゲットとするアプリは、
- 記載されている条件を満たし、
- これらの例外に基づいてバックグラウンド アクティビティの起動を許可するようにオプトインする必要があります。
このオプトインは、アプリ デベロッパーがアプリが Activity を起動することがわかっている場合にのみ 行う必要があります。
オプトインするには、アプリはActivityOptions バンドルを
setPendingIntentBackgroundActivityStartMode(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
PendingIntent.send() などのメソッドに渡す必要があります。
PendingIntent の作成者による
ほとんどの場合、PendingIntent を起動するアプリがオプトインする必要があります。
ただし、作成アプリが次の権限を付与する必要がある場合は、
- 作成アプリが表示されているときはいつでも
PendingIntentを起動できます。 - 作成アプリに特別な権限がある場合は、いつでも
PendingIntentを起動できます。
オプトインするには、アプリは ActivityOptions バンドルを
setPendingIntentCreatorBackgroundActivityStartMode
(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED) に
PendingIntent.getActivity() などのメソッドに渡す必要があります。
詳細については、関連するリファレンス ドキュメントをご覧ください。
ActivityOptions.setPendingIntentBackgroundActivityStartModeActivityOptions.setPendingIntentCreatorBackgroundActivityStartMode
厳格モード
Android 16 以降では、アプリ デベロッパーは厳格モードを有効にして、アクティビティの起動がブロックされた場合(またはアプリのターゲット SDK が引き上げられたときにブロックされる可能性がある場合)に 通知を受け取ることができます。
Application、Activity、その他のアプリケーション コンポーネントの Application.onCreate() メソッドの早い段階で有効にするコード例を次に示します。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectBlockedBackgroundActivityLaunch()
.penaltyLog()
.build());
)
}
詳しくは、厳格モードのドキュメントをご覧ください。