このページでは、フォアグラウンド サービスが失敗する一般的な理由と、問題の原因を特定する方法について説明します。
このドキュメントでは、次の問題について説明します。
トラブルシューティングの前に
フォアグラウンド サービスの最近の変更を確認する
フォアグラウンド サービスを不適切な方法で使用すると、デバイスのパフォーマンスやバッテリー駆動時間に悪影響を及ぼす可能性があります。このため、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() を呼び出すようにします。
WorkManager:
この例外は、フォアグラウンド サービスを実行する(setForegound または setForegroundAsync を呼び出す)WorkManager ワーカーでも発生する可能性があります。2 つのフォアグラウンド ワーカーのライフサイクルが重複し、以前に実行されていたフォアグラウンド サービスがシャットダウンしようとしているときに、1 つのワーカーがフォアグラウンド サービスを開始しようとすると、このクラッシュが発生し、次のログが記録されます。
Re-initializing SystemForegroundService after a request to shut-down
このクラッシュの修正は、WorkManager バージョン 2.10.5 で導入されました。
アプリでこの例外が発生した場合は、WorkManager の最新バージョンに更新し、解決しない問題があれば WorkManager の Issue Tracker で報告してください。
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が発生することがあります。
- 必要な権限をリクエストしたものの、必要な権限が付与されたことを確認する前にフォアグラウンド サービスを開始すると、
解決方法:
フォアグラウンド サービスを起動する前に、適切なフォアグラウンド サービス権限をすべてリクエストし、他のすべてのランタイム前提条件を満たしていることを確認します。