I am writing an Android app to alert the user an event in "almost" real time. The app sends an HTTP Get request asynchronously, and processes the received result when it arrives to determine the state of the event. To be reasonably up-to-date, the HTTP requests need to be made every 15-60 seconds.
I have implemented this using a foreground service, thinking this would allow the alert when the app is in the background. The service contains the following code to handle the recurring requests (with an AsyncTask subclass to handle the actual HTTP request):
Handler queryHandler = new Handler();
runQuery = new Runnable() {
@Override
public void run() {
new HTTPGetTask().execute(urlString);
queryHandler.postDelayed(runQuery, queryFrequencyInMilliseconds);
}
};
It works fine until the device sleeps. Then the service sleeps as well, only waking and reporting status at intervals that are far too long to be useful.
I've been reading about AlarmManagers, Partial WakeLocks, WakefulBroadcastReceivers, and Job Schedulers. (e.g., Keep a Service running even when phone is asleep). I need to target older devices (API level 19) so the JobScheduler approach is out.
There are clearly a number of approaches to scheduling recurrent tasks, but it seems that the best approach depends a number of factors, including length of task, frequency of task, how precise the timing needs to be. For example, Android documentation on AlarmManager states
Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.
Any suggestions on best approach / design pattern for an HTTP request repeating every 15 - 60 seconds, given that the returned result is small, and that the user needs to get the result in a timely fashion when the app is in the background and even if the device sleeps? The timing doesn't need to be exact, but should be reasonably consistent.
(edited to add) Typical use case is that the service would be in operation for 5 to 30 minutes, and would stop once a final event state had been received and the user alerted. I would also probably have a maximum allowed running time of 30 - 60 minutes.