AlarmManager setExact с WakefulBroadcastReceiver иногда не точный
Использование Android 19 +
setExact в соединении с WakefulBroadcastReceiver иногда не срабатывает вовремя (может быть несколько секунд или так поздно). Я имею в виду большую часть времени. вероятно, 49 раз из 50 правильных.
Я не уверен, что это только потому, что система занята в то время и не может обрабатывать рабочую нагрузку или что
Вот как я устанавливаю будильник:
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(AlarmReceiver.INTENT_FILTER);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, MyApplication.ALARM_REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.setExact(AlarmManager.RTC_WAKEUP, timeToWakeUp, alarmIntent);
Вот мой код приемника:
public class AlarmReceiver extends WakefulBroadcastReceiver {
public static final String INTENT_FILTER = "myfilter";
@Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, MyWakefulService.class);
startWakefulService(context, service);
}
}
И в программе WakefulService
public class MyWakefulService extends IntentService {
....
@Override
protected void onHandleIntent(Intent intent) {
....
Ответы
Ответ 1
Такое поведение добавляется в API 19:
Начиная с доставки сообщений API 19 (KITKAT) неточно: ОС сбрасывает аварийные сигналы, чтобы свести к минимуму пробуждения и использование батареи. Существуют новые API-интерфейсы для поддержки приложений, требующих строгих гарантий доставки; см. setWindow (int, long, long, PendingIntent) и setExact (int, long, PendingIntent). Приложения, чья targetSdkVersion ранее, чем API 19, будут продолжать видеть предыдущее поведение, при котором все сигналы тревоги отправляются точно по запросу.
из AlarmManager.
Важно: setExact()
по-прежнему не обязательно быть точным, поскольку состояние документов:
Тревога будет доставлена как можно ближе к запрошенному времени запуска.
Ответ 2
В эпоху Зефира (?) нам нужны некоторые уродливые коды, например ниже...:(
Параметр "delayInMillis" должен быть более 15 минут на API 23.
Если нет, система игнорирует минуты менее 15 минут.
private void registerExactAlarm(PendingIntent sender, long delayInMillis) {
final int SDK_INT = Build.VERSION.SDK_INT;
AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
long timeInMillis = (System.currentTimeMillis() + delayInMillis) / 1000 * 1000; //> example
if (SDK_INT < Build.VERSION_CODES.KITKAT) {
am.set(AlarmManager.RTC_WAKEUP, timeInMillis, sender);
}
else if (Build.VERSION_CODES.KITKAT <= SDK_INT && SDK_INT < Build.VERSION_CODES.M) {
am.setExact(AlarmManager.RTC_WAKEUP, timeInMillis, sender);
}
else if (SDK_INT >= Build.VERSION_CODES.M) {
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timeInMillis, sender);
}
}