Android 8.0でBOOT_COMPLETEDを受信後のサービス起動が失敗する問題を回避
Android 8.0で、端末の再起動時に「android.intent.action.BOOT_COMPLETED」を受信し、サービスを起動したら失敗します。
失敗しないように呼び出す関数を変更しましょう。
スポンサーリンク
もくじ
結論
サービス起動を次のように変えてください。
変更前
context.startService(newIntent);
変更後
ContextCompat.startForegroundService(context, intent);
ちなみにこのメソッドの内部は次のようなものになっています。
/**
* startForegroundService() was introduced in O, just call startService
* for before O.
*
* @param context Context to start Service from.
* @param intent The description of the Service to start.
*
* @see Context#startForegeroundService()
* @see Context#startService()
*/
public static void startForegroundService(Context context, Intent intent) {
if (Build.VERSION.SDK_INT >= 26) {
context.startForegroundService(intent);
} else {
// Pre-O behavior.
context.startService(intent);
}
}
ざっくり解説
詳細は「Preview > Oreo > バックグラウンド実行制限」を読んでください。
簡単に言うと、バックグラウンドサービスの制限です。
フォアグラウンドにあると見なされる状態にすることで回避します。
アプリは、以下のいずれかに該当する場合にフォアグランドにあると見なされます。
- 可視アクティビティがある(アクティビティが開始されているか一時停止されているかに関係なく)。
- フォアグラウンド サービスを使用している。
- 別のフォアグラウンド アプリが該当アプリのいずれかのサービスにバインドされるか、該当アプリのいずれかのコンテンツ プロバイダを使用することで、フォアグラウンド アプリが該当アプリに接続している。 たとえば、別のアプリが次のいずれかのサービスにバインドされると、アプリがフォアグラウンドになります。
- IME
- 壁紙サービス
- 通知リスナー
- 音声またはテキスト サービス
これらのいずれの条件にも該当しない場合、アプリはバックグラウンドにあると見なされます。
よって、フォアグラウンドでサービスを起動するように変更しています。
暗黙的なブロードキャストの例外
target APIレベル26以上のアプリは、暗黙的なブロードキャストはmanifestに登録できないようになっています。しかし、いくつかのブロードキャストは例外となっています。これにより「ACTION_BOOT_COMPLETED(android.intent.action.BOOT_COMPLETED)」はブロードキャストを受信できます。
詳細は次を参照してください。
Implicit Broadcast Exceptions(暗黙的なブロードキャストの例外)