Wakefulbroadcastreceiver -> Intentservice не выполняется в "глубоком" сне
У нас есть некоторые проблемы с бизнес-кейсом. Цель, которую мы пытаемся заархивировать, состоит в том, чтобы иметь приложение, которое проверяет каждые 30 секунд, даже в каждом режиме ожидания / сна, на наличие новых данных из веб-службы JSON.
МЫ ЗНАЕМ -> Обращение в веб-службу часто оказывает огромное влияние на время автономной работы. -> Нажатие является лучшим решением, чем опрос, но в нашем случае по другим причинам безопасности это невозможно.
Клиентское устройство в настоящее время работает на Android Kitkat, а мое тестовое устройство работает на Nougat (что не облегчает:/)
После нескольких часов поисков и поисков я нашел следующее решение.
У меня есть Wakefulbroadcastreceiver, который вызывает службу intent в методе onreceive и сбрасывает сигнал тревоги. Пока что все работает нормально. Сигнал тревоги срабатывает регулярно.
public class AlarmManagerHandler extends WakefulBroadcastReceiver {
public Context context;
@Override
public void onReceive(Context context, Intent intent) {
this.context = context;
Intent service = new Intent(context, EmergencyOrderWakefulService.class);
startWakefulService(context, service);
setAlarm(context);
}
public void setAlarm(Context context) {
try {
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, AlarmManagerHandler.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(
System.currentTimeMillis() + EmergencyOrderController.REPEAT_WEBREQUEST, pi);
alarmMgr.setAlarmClock(alarmClockInfo, pi);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmMgr.setExact(android.app.AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + EmergencyOrderController.REPEAT_WEBREQUEST, pi);
} else {
alarmMgr.set(android.app.AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + EmergencyOrderController.REPEAT_WEBREQUEST, pi);
}
} catch (Exception ex) {
Log.e(EmergencyOrderController.LOGCATGROUP, "AlarmManagerHandler.setAlarm(Context):" + ex.getMessage());
}
}
Вот как выглядит мой интентсервис:
public class WakefulService extends IntentService {
public WakefulService() {
super("WakefulService");
}
@Override
protected void onHandleIntent(Intent intent) {
//aquire wakelock for the webservice request to avoid CPU goes back to sleep during execution
PowerManager pm = (PowerManager) EmergencyOrderController.getInstance().getContext().getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
new WebRequestHandler().executeWebRequest();
wl.release();
// explicitly release the waklock of the WakefulBroadcastReceiver
AlarmManagerHandler.completeWakefulIntent(intent);
}
}
Файл журнала на веб-сервере показывает, что в течение некоторого времени ничего не происходило, например, в течение 15 минут, после этого 30 запросов приходили подряд.
Поэтому я предполагаю, что AlarmManager выполняется правильно и запускает намерение, которое затем должно вызвать IntentService, но эти намерения были поставлены в очередь (даже с явным wakelock) и выполнены, как только система решила, что достаточно "материала" накопилось для пробуждения CPU вверх и выполнить.
У кого-нибудь есть идеи, как решить эту проблему?