Диспетчер повторных тревог Android не срабатывает немедленно

Мой код:

Calendar calSet = Calendar.getInstance();
calSet.set(Calendar.HOUR_OF_DAY, 11);
calSet.set(Calendar.MINUTE, 20);
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);

PendingIntent pi=PendingIntent.getBroadcast(context,0,myIntent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,calSet.getTimeInMillis(),pi);

и сказать, я выполняю в 11:30. Тревога срабатывает немедленно (что ожидаемо). Но для того же, когда я использую

alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calSet.getTimeInMillis(),24*60*60*1000,pi);

тревога срабатывает не сразу. Есть задержка до 1 минуты (чего не ожидается). Я хочу, чтобы повторяющийся будильник срабатывал немедленно, без задержки.

Может ли кто-нибудь помочь мне с этим?


person Ravindra    schedule 04.01.2015    source источник
comment
НЕВЕРОЯТНОЕ ПРЕДПОЛОЖЕНИЕ: вы ориентируетесь на API уровня 19+   -  person Phantômaxx    schedule 04.01.2015
comment
@Der Golem minSdkVersion 11 targetSdkVersion 21   -  person Ravindra    schedule 04.01.2015
comment
Понимаете? Я был прав — именно поэтому я использую targetSdkVersion 18.   -  person Phantômaxx    schedule 04.01.2015
comment
я предполагаю, что ответ, который вы ищете, находится здесь: .com/questions/20438405/ проверьте это   -  person Ahmad Sanie    schedule 04.01.2015
comment
@AhmadAlsanie: я обновил код, чтобы сбросить как «секунды», так и «миллисекунды», но все еще не работает. Есть задержка.   -  person Ravindra    schedule 04.01.2015
comment
developer.android.com/reference/android/app/AlarmManager.html: Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use.   -  person Phantômaxx    schedule 04.01.2015
comment
@DerGolem: Как вы сказали, он отлично работает, когда я устанавливаю для targetSdkVersion значение 18. Предположим, если я соберу свое приложение с версией targetSdk до 18, создаст ли это какие-либо проблемы при установке на устройства Android с более высоким API (›18)?   -  person Ravindra    schedule 04.01.2015
comment
Вообще не проблема, зачем? Если это так, старые приложения, созданные для API уровня 14, не должны работать на новых устройствах... но они работают, поскольку Android обратно совместим.   -  person Phantômaxx    schedule 04.01.2015
comment
@DerGolem: я обычно ориентируюсь на последнюю версию. Итак, я спросил. Большое спасибо :-). Если вы опубликуете свой комментарий в качестве ответа, я буду рад принять его.   -  person Ravindra    schedule 04.01.2015
comment
Не всем понравится мой ответ. Многие из них следят за модой, поэтому они заинтересованы в материальном дизайне. Я рискую получить много отрицательных голосов, если опубликую такой ответ. Ответ @hqt правильный (+1), поэтому вместо этого вы можете принять его ответ.   -  person Phantômaxx    schedule 04.01.2015


Ответы (1)


Вы должны изменить свой код на:

PendingIntent pi=PendingIntent.getBroadcast(context,0,myIntent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
      alarmManager.setExact(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(), pi);
} else {
      alarmManager.set(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(), pi);
}

@Edit Приведенный выше код будет работать в течение установленного времени. Но в этом разделе будет рассказано о повторении для менеджера тревог.

Для API ниже 19 мы используем AlarmManager.setRepeating(), чтобы периодически срабатывать будильники точно в указанное время. Но с версии 19 и новее этот метод больше не будет работать, и API не поддерживает такое поведение. Я думаю, что это изменение API заставляет разработчиков думать более тщательно, когда они создают таймер. Потому что запуск таймера в точное время периодически сильно разряжает батарею.

Если вы хотите, вы должны сделать это самостоятельно. Во-первых, вы устанавливаете AlarmManager.setExact(), и при срабатывании будильника вы снова сработаете в следующий раз вручную.

Вот код:

PendingIntent pi=PendingIntent.getBroadcast(context,0,myIntent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
     alarmManager. setExact(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(), pi);
} else {
     alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(), pi);
}

И в вашем намерении, где вы помещаете код дескриптора, вы должны проверить, если android api> = 19, приложение создаст новый сигнал тревоги для следующего события.

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
         doSomething();
         // calculate time for next event
         Calendar nextEvent = calcNextEvent();
         // and set alarm again
         alarmManager. setExact(AlarmManager.RTC_WAKEUP, nextEvent.getTimeInMillis(), pi);
 } else {
         doSomething();
 }

Я думаю, что это проблема в дизайне Android API. Старый код должен работать в новой версии. В любом случае, этот новый дизайн API делает все понятнее для разработчика, лучше для системы (экономия заряда батареи). Конечно, при использовании нового API :)

Надеюсь, это поможет :)

person hqt    schedule 04.01.2015
comment
Я думаю, это не повторяющийся будильник. Я ищу повторную тревогу. - person Ravindra; 04.01.2015
comment
@Ravindra, я отредактировал свой пост. вы можете снова увидеть :) В основном, из API ›= 19. вы должны сделать это вручную - person hqt; 04.01.2015
comment
@hqt Я повторил точно так, как вы написали здесь, проблема, с которой я столкнулся, заключается в том, что мой широковещательный приемник вызывается примерно 10-30 раз (кажется случайным) на моем устройстве с леденцами. Он использует setExact для запуска будильника, и когда он срабатывает, он снова выполняет setExact (что должно произойти через 1 день, но он вызывается сразу 10-30 раз). Знаете в чем может быть причина? Вы можете помочь мне здесь? Спасибо - person Makks129; 06.07.2015