私自身のアプリは、2016年のGoogle I/Oアプリで示されているものとまったく同じ手法を使用しています。 ソースを参照
通知を使用して、非常に特定の時点でユーザーに通知する必要があります。
このために、AlarmManager
を使用してデバイスを正しい時点でウェイクします:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat) {
am.setExact(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
} else {
am.set(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
}
pendingIntent
は次のように作成されます。
final Intent intent = new Intent(MyAlarmService.ACTION_NOTIFY_RIDE, null, this, MyAlarmService.class);
pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
さて、私のMyAlarmService
クラスは単純なIntentService
であり、ユーザーへの通知を作成するためだけにウェイクアップを処理します。
ログに記録されるメッセージは次のとおりです。
W/ActivityManager: Background start not allowed: service Intent { act=xxx.xxx.xxx.action.NOTIFY_RIDE flg=0x4 cmp=xxx.xxx.xxx./xxx.xxx.xxx.service.MyAlarmService (has extras) }
今、Google自身の実装は明らかに壊れています-重いバックグラウンド作業をしたくないが、このテクニックはもう使用できません。しかし、その後、非常に特定の時点でユーザーをどのように起こすのですか? (私のアプリを目覚まし時計と考えてください)
私の質問への答えは単純明快です。
サービスを使用して通知を表示する代わりに(GoogleがIOアプリをスケジュールする!)で行うように)、BroadcastReceiverを使用してください!
GoogleがなぜIntentServiceを使用したのかはわかりませんが、今はAndroid O、これはバックグラウンド実行の制限により、もう機能していません。
ただし、BroadcastReceiverは、まだ少しの間実行され、通知を表示できます。
Googleが最初にIntentServiceを使用した理由を誰かが教えてくれたらボーナスポイント... Googleは彼らが何をしているのか知っていると思ったので、これを理解するのに年齢がかかりました...
しかし、その後、非常に特定の時点でユーザーをどのように起こすのですか? (私のアプリを目覚まし時計と考えてください)
まず、コードは正確ではありません。デバイスがDozeモードの場合、せいぜい+/- 10分しか期待できません。正確なタイミングが必要で、アプリが本当に目覚まし時計である場合は、setAlarmClock()
を使用します。
既存のコードの場合、 APIレベル26以降でgetForegroundService()
の代わりにgetService()
を使用します。
SyncAdapter/Job Schedulerを定期的に実行して同じビジネスロジックを実行することも考えられます。また、新しい定期的な同期を設定するには、アプリケーションの起動自体で初めて行うことができます。