AlarmManager on API19には、正確なアラームを設定するためのメソッドsetExact()があります。
正確な意味->アラームを午後2時1分に設定すると、午後2時1分にトリガーされます
On API 23-Marhsmwallow(6.0)新しいメソッドsetExactAndAllowWhileIdle()がありますが、参照の時点ではトリガーされるだけなので、EXACTではありませんevery分および低電力アイドルモードのみ15分ごと。
完全!= 15分ごと:-)
では、AlarmManagerで6.を使用してexact alarmを実現するにはどうすればよいですか。
ユーザーがリマインダーまたはカレンダーの予定を追加し、イベントの10分前に通知されるようにするには、アラームを表示する必要がありますEXACT 10 minutes beforeイベント。 setExactAndAllowWhileIdle()では、これは不可能のようです。
6.0のAlarmManagerで正確なアラームを実現するにはどうすればよいですか?
try setAlarmClock()
を歓迎します。知っている限り、Dozeモードの影響を受けません。それ以外の場合、AlarmManager
は実行可能なオプションではありません。 AlarmManager
動作はホワイトリストに基づいて変化しないため、バッテリー最適化ホワイトリストにアプリを追加しても役に立ちません。
優先度の高いメッセージがユーザーに警告する機会を与えるため、GCMを使用することを歓迎します。もちろん、これにはネットワーク接続が必要です。
私が知っている唯一のオフラインソリューションは、ユーザーにアプリをバッテリー最適化ホワイトリストに追加してもらい、フォアグラウンドサービスを使用して(プロセスを維持しようとする)、ScheduledExecutorService
(タイミング用)、および部分的なWakeLock
(CPUをオンに維持するため)。これは、ユーザーのバッテリーをかなり破壊します。
1回限りのアラームにsetExactAndAllowWhileIdle()を使用すると、Dozeアイドルモードであっても、指定された時間に正確に起動します。だから、これはおそらく行く方法です。
15分未満の間隔でアラームを繰り返したい場合(または、最後のアラームから15分以内に他の時間を設定する場合) Dozeアイドルモードでは動作しません。このようなアラームは次の15分間に強制されるか、アイドルメンテナンスの開始時に実行されます。これは、最初は1時間後、さらに2時間後、さらに4時間後など、 。
-編集-
今日の11月17日の時点で、Dianne Hackbornが this Post のコメントに次のように書いています: "価値があるため、アイドルアラームの最小間隔は一部のポイントは比較的すぐに(現在のMarshmallowビルドを実行しているデバイス上でも)。 "
しかし、これは根本的に何も変更しません。
これまでのところ、AbstractThreadedSyncAdapterを拡張するSyncAdapterを使用することが最良のオプションであることがわかりました。必要な間隔でコードを自動的に実行し続けるようにスケジュールします。
ContentResolver.setSyncAutomatically(account, AUTHORITY, true);
ContentResolver.addPeriodicSync(account, AUTHORITY, settingsBundle, syncInterval);
バックグラウンドで実行される自動化システムを作成しようとしていました。周波数範囲は1〜15分でした。私の願いは、フォアグラウンドサービスを使用しないことでした。メソッド「setExactAndAllowWhileIdle」の名前を見ることで、1回限りのアラームを実行し、完了したら次のアラームをスケジュールしても安全だと思いました。
ただし、アラームが15分より頻繁に実行されている状態で、居眠りモードでコードを実行する方法が見つかりませんでした。代わりに、居眠りモードがアクティブになったときにフォアグラウンドサービスを開始し、電話が起動したときにフォアグラウンドサービスを停止することを選択します。ユーザーは、自分の電話の使用中に前景通知を見ることができません。私は居眠りモードのものについてはあまり気にしません。
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(intent.getAction().equals("Android.os.action.DEVICE_IDLE_MODE_CHANGED")){
if (pm.isDeviceIdleMode()) {
//startAutomationForegroundService();
} else {
//stopAutomationForegroundService();
return;
}
AutomationReceiver.completeWakefulIntent(intent);
return;
}
}
「Android.os.action.DEVICE_IDLE_MODE_CHANGED」インテントフィルターをWakefulBroadcastReceiverに登録する必要があります。それをマニフェストに入れることは助けにならないかもしれません。