フォアグラウンド サービスのトラブルシューティング

このページでは、フォアグラウンド サービスが失敗する一般的な理由について説明し、問題の原因を特定するのに役立ちます。

このドキュメントでは、次の問題について説明します。

トラブルシューティングの前に

フォアグラウンド サービスの最近の変更を確認する

フォアグラウンド サービスを不適切に使用すると、デバイスのパフォーマンスやバッテリー駆動時間に悪影響を及ぼす可能性があります。そのため、Android プラットフォームのリリースでは、こうした悪影響を制限するためにフォアグラウンド サービスの動作が頻繁に変更されています。

フォアグラウンド サービスで問題が発生した場合は、フォアグラウンド サービスの変更に関するドキュメントを確認し、問題の原因となる最近の変更がないか確認してください。特に、次のような状況では変更を確認することが重要です。

  • 以前は動作していたフォアグラウンド サービス コードが失敗する
  • 新しいプラットフォーム リリースでのテストを開始したばかりである、またはアプリのターゲット API レベルを変更した

また、プラットフォームのデベロッパー プレビューでデバイスをテストする場合は、デベロッパー プレビューのドキュメントの最新バージョンを確認してください。

アプリケーション応答なし(ANR)エラー

特定の状況下では、アプリはフォアグラウンド サービスをシャットダウンすることが想定されています。アプリがサービスを停止しない場合、システムがサービスを停止し、アプリケーション応答なし(ANR)エラーをトリガーします。

ショート サービスの実行時間が長すぎて ANR が発生する

ショート サービス タイプを使用するフォアグラウンド サービスは、約 3 分以内に迅速に完了する必要があります。時間が経過すると、システムはサービスの Service.onTimeout(int,int) メソッドを呼び出します。サービスは stopSelf() を呼び出すまでに数秒かかります。サービスが自動的に停止しない場合、システムはアプリケーション応答なしエラーをトリガーします。

診断:

フォアグラウンド サービスが停止に失敗したことが原因で ANR が発生した場合、システムは内部例外をスローします。ANR レポートを確認することで、これが問題であったことを確認できます。この問題が原因の場合、レポートには次のメッセージが表示されます。

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type FOREGROUND_SERVICE_TYPE_SHORT_SERVICE did not stop within its timeout:
[component name]"

解決方法:

時間制限付きのフォアグラウンド サービスがすべて、システムの時間制限内に処理を完了し、stopForeground(int) を呼び出すようにします。

フォアグラウンド サービスに Service.onTimeout(int,int) を実装します。そのメソッドの実装で stopSelf() がすぐに呼び出されるようにしてください。

フォアグラウンド サービスの例外

このセクションでは、システムが例外をスローする原因となるフォアグラウンド サービスのいくつかの問題について説明します。アプリが例外をキャッチしない場合、アプリが停止したことを知らせるダイアログがユーザーに表示されます。

場合によっては、システムが内部例外をスローします。このような場合は、スタック トレースを確認して例外の内容を把握できます。また、Logcat でエラーの詳細情報を確認することもできます。

内部例外: タイムアウトを超過しました

アプリがバックグラウンドにあるときにデータ同期とメディア処理のフォアグラウンド サービスを実行できる時間について、システムが制限を課します。サービスがその上限を超えると、システムはサービスの Service.onTimeout(int,int) メソッドを呼び出します。サービスには stopSelf() を呼び出すための数秒間があります。サービスが自動的に停止しない場合、システムは内部 RemoteServiceException を生成し、アプリがクラッシュします。

診断:

例外の内容は、スタック トレースを確認することで把握できます。また、Logcat でエラーの詳細情報を確認することもできます。この場合、Logcat に次のエラー メッセージが表示されます。

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type [service type] did not stop within its timeout: [component name]"

解決方法:

時間制限付きのフォアグラウンド サービスがすべて、システム時間制限内に処理を完了して stopForeground(int) を呼び出すようにします。

フォアグラウンド サービスに Service.onTimeout(int,int) を実装します。そのメソッドの実装で stopSelf() がすぐに呼び出されるようにしてください。

内部例外: ForegroundServiceDidNotStartInTimeException

context.startForegroundService() を呼び出してサービスを起動すると、そのサービスは ServiceCompat.startForeground() を呼び出してフォアグラウンド サービスに昇格するまで数秒間あります。サービスがそうしない場合、内部 ForegroundServiceDidNotStartInTimeException をスローします。

診断:

例外の内容は、スタック トレースを確認することで把握できます。また、Logcat でエラーの詳細情報を確認することもできます。この場合、Logcat に次のエラー メッセージが表示されます。

android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException:
Context.startForegroundService() did not then call Service.startForeground()

解決方法:

新しく作成されたすべてのフォアグラウンド サービスが数秒以内に ServiceCompat.startForeground() を呼び出すようにしてください。

ForegroundServiceStartNotAllowedException

エラー:

システムが ForegroundServiceStartNotAllowedException をスローします。

原因:

これは通常、有効な除外がない場合にアプリがバックグラウンドからフォアグラウンド サービスを起動することが原因で発生します。

Android 12(API レベル 31)以降では、いくつかの特定の例外を除き、アプリがバックグラウンドで実行されているときにフォアグラウンド サービスを開始することは許可されません。バックグラウンドからフォアグラウンド サービスを開始しようとして、除外の要件のいずれも満たしていない場合、システムは ForegroundServiceStartNotAllowedException をスローします。免除の要件を満たしていない場合も、同様の処理が行われます。

たとえば、ユーザーがクリックできるボタンがアプリにあり、そのボタンをクリックすると、アプリが何らかの処理を行い、フォアグラウンド サービスを起動する場合があります。この場合、ユーザーがボタンをクリックしてすぐにアプリをバックグラウンドに移行する可能性があります。アプリはバックグラウンドからサービスの起動を試みます。アプリが指定された除外条件のいずれかを満たしていない場合、システムは ForegroundServiceStartNotAllowedException をスローします。

また、一部の例外には短い期限が設定されています。たとえば、優先度の高い FCM メッセージに応答してアプリがフォアグラウンド サービスを起動する場合、短い免除期間があります。サービスを十分に早く起動しないと、ForegroundServiceStartNotAllowedException が発生します。

特定の免除は、新しい Android リリースで制限が厳しくなることがあります。アプリのターゲットとする Android のバージョンを変更した場合は、フォアグラウンド サービスの変更に関するドキュメントを確認し、アプリが引き続き許可されている例外のいずれかを満たしていることを確認してください。

解決方法:

アプリがバックグラウンドにあるときにフォアグラウンド サービスを起動する必要がないようにアプリのワークフローを変更するか、アプリが免除のいずれかの条件を満たしていることを確認します。

ライフサイクル対応コンポーネントを使用すると、アプリのライフサイクルを管理して、バックグラウンドからフォアグラウンド サービスを誤って起動しようとすることを防ぐことができます。

SecurityException

エラー:

システムが SecurityException をスローします。

原因:

アプリが、必要な権限がない状態でフォアグラウンド サービスを起動しようとしました。

  • アプリが Android 9(API レベル 28)以上をターゲットとしている場合、フォアグラウンド サービスを起動するには FOREGROUND_SERVICE 権限が必要です。
  • アプリが Android 14(API レベル 34)以上をターゲットとしている場合、フォアグラウンド サービス タイプのすべての前提条件を満たしている必要があります。これらの前提条件については、フォアグラウンド サービス タイプのドキュメントで詳しく説明しています。特に、次の要件に注意してください。
    • いくつかのフォアグラウンド サービス タイプでは、特定の実行時の権限が必要です。たとえば、リモート メッセージング フォアグラウンド サービスには FOREGROUND_SERVICE_REMOTE_MESSAGING 権限が必要です。
  • 一部のフォアグラウンド サービスのタイプに必要な権限には、使用中の追加の制限が課せられている場合があります。これらの権限は、アプリがフォアグラウンドにある間のみアプリに付与されます(いくつかの例外があります)。つまり、アプリがこれらの権限のいずれかをリクエストして付与された場合でも、アプリがバックグラウンドにあるときにフォアグラウンド サービスを起動しようとすると、アプリがバックグラウンドからフォアグラウンド サービスを起動する免除を受けている場合でも、システムは SecurityException をスローします。詳しくは、使用中の権限が必要なフォアグラウンド サービスの開始に関する制限をご覧ください。
    • 必要な権限をリクエストしたものの、必要な権限が付与されたことを確認する前にフォアグラウンド サービスを開始すると、SecurityException が発生する可能性があります。

解決方法:

フォアグラウンド サービスを起動する前に、適切なフォアグラウンド サービス権限をすべてリクエストし、他のすべてのランタイム前提条件を満たしていることを確認します。