このページでは、フォアグラウンド サービスが失敗する一般的な理由と、問題の原因を特定する方法について説明します。
このドキュメントでは、次のトピックについて説明します。
トラブルシューティングの前に
フォアグラウンド サービスに最近加えられた変更を確認する
フォアグラウンド サービスを不適切に使用すると、デバイスのパフォーマンスやバッテリー駆動時間に悪影響が及ぶ可能性があります。そのため、Android プラットフォームのリリースでは、フォアグラウンド サービスの動作が変更され、こうした悪影響を抑制することがよくあります。
フォアグラウンド サービスで問題が発生している場合は、フォアグラウンド サービスの変更に関するドキュメントで、問題の原因となる最近の変更がないかどうかを確認してください。特に、以下の状況では変更を確認することが重要です。
- 以前は動作していたフォアグラウンド サービス コードが動作しなくなった
- 新しいプラットフォーム リリースでのテストを開始した、またはアプリがターゲットとする API レベルを変更した
また、プラットフォームのデベロッパー プレビューでデバイスをテストしている場合は、最新バージョンのデベロッパー プレビューのドキュメントを確認してください。
アプリケーション応答なし(ANR)エラー
特定の状況下では、アプリはフォアグラウンド サービスをシャットダウンすることが求められます。アプリがサービスを停止しない場合、システムはサービスを停止し、アプリケーション応答なし(ANR)エラーをトリガーします。
ショート サービスが長時間実行され、ANR が発生する
短時間サービス タイプを使用するフォアグラウンド サービスは、約 3 分以内に完了する必要があります。時間が経過すると、システムはサービスの Service.onTimeout(int,int)
メソッドを呼び出します。サービスは stopSelf()
を呼び出すために数秒間待機します。サービスが自動的に停止しない場合、システムはアプリケーション応答なしエラーをトリガーします。
診断:
フォアグラウンド サービスが自身を停止できなかったために ANR が発生した場合、システムは内部例外をスローします。これが問題であることを確認するには、Logcat を確認します。この場合、ログには次のメッセージが含まれます。
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()
を呼び出すために数秒間あります。サービスが停止しない場合、システムは内部例外を生成してアプリをクラッシュさせます。
診断:
タイムアウトが原因の場合は、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()
を呼び出してフォアグラウンド サービスに昇格するまでの数秒間があります。サービスがこれを行わないと、システムは ANR エラーをトリガーします。
診断:
フォアグラウンド サービスが時間内に開始されなかった場合、アプリはクラッシュし、[アプリが停止しました] ダイアログが表示されます。この場合、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 のバージョンを変更した場合は、フォアグラウンド サービスの変更に関するドキュメントを確認し、アプリが引き続き許可されている例外のいずれかに該当することを確認してください。
解決方法:
アプリがバックグラウンドにあるときにフォアグラウンド サービスを起動する必要がないようにアプリのワークフローを変更するか、アプリが免除のいずれかに該当することを確認します。
LiveData
などのライフサイクル コンポーネントを使用してアプリのライフサイクルを管理することで、バックグラウンドからフォアグラウンド サービスを誤って起動しようとするのを防ぐことができます。
SecurityException
エラー:
システムが SecurityException
をスローします。
原因:
アプリが必要な権限を取得せずにフォアグラウンド サービスを起動しようとしました。
- Android 9(API レベル 28)以降をターゲットとするアプリは、フォアグラウンド サービスを起動するための
FOREGROUND_SERVICE
権限が必要です。 - アプリが Android 14(API レベル 34)以降をターゲットとしている場合、フォアグラウンド サービス タイプの前提条件をすべて満たす必要があります。これらの前提条件については、フォアグラウンド サービス タイプのドキュメントをご覧ください。特に、次の要件に注意してください。
- 一部のフォアグラウンド サービスのタイプには、特定のランタイム権限が必要です。たとえば、リモート メッセージ フォアグラウンド サービスには
FOREGROUND_SERVICE_REMOTE_MESSAGING
権限が必要です。
- 一部のフォアグラウンド サービスのタイプには、特定のランタイム権限が必要です。たとえば、リモート メッセージ フォアグラウンド サービスには
- 一部のフォアグラウンド サービス タイプで必要な権限には、使用中の追加の制限が適用される場合があります。これらの権限は、アプリがフォアグラウンドにある間のみアプリに付与されます(一部の例外を除く)。つまり、アプリがこれらの権限のいずれかをリクエストして付与されている場合でも、アプリがバックグラウンドでフォアグラウンド サービスを起動しようとすると、アプリがバックグラウンドからフォアグラウンド サービスを開始するための免除を受けていても、システムは
SecurityException
をスローします。詳細については、使用中の権限が必要なフォアグラウンド サービスの開始に関する制限をご覧ください。- 必要な権限をリクエストしたが、必要な権限が付与されたことを確認する前にフォアグラウンド サービスを開始した場合、
SecurityException
が返されることがあります。
- 必要な権限をリクエストしたが、必要な権限が付与されたことを確認する前にフォアグラウンド サービスを開始した場合、
解決方法:
フォアグラウンド サービスを起動する前に、適切なフォアグラウンド サービス権限をすべてリクエストし、他のすべてのランタイムの前提条件を満たしていることを確認します。