My hybrid Cordova Android app uses one custom plugin in which I do a great deal of background work at intervals of ca 30 minutes. Up until now I have been using AlarmManger
with a setInexact
alarm to perform the work. The only real issue I have with that route is that the alarm does not survive a reboot. Given that I am now only supporting Android 6 (API 23)+ devices I am now experimenting with replacing AlarmManager
with JobScheduler
. My efforts thus far are shown below
public class UnyService extends JobService
{
@Override
public boolean onStartJob(JobParameters params)
{
UnyHandler.sendMessage(Message.obtain(UnyHandler,1,params));
return true;
}
@Override
public boolean onStopJob(JobParameters params)
{
UnyHandler.removeMessages(1);
return false;
}
where I am using a Handler
to perform the actual work. The code for Handler
is shown below
private Handler UnyHandler = new Handler(new Handler.Callback()
{
@Override
public boolean handleMessage(Message msg)
{
Feedback.postBackInfo("Handled it!");
jobFinished((JobParameters)msg.obj,false);
return true;
}
});
I then use the following code to get the job up and running
private void launchTimerJob()
{
timerJob =
(JobScheduler)context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo.Builder builder = new JobInfo.Builder(1,new
ComponentName(Utils.packName,UnyService.class.getName()));
builder.setPeriodic(30000);
builder.setPersisted(true);
builder.setBackoffCriteria(30000,JobInfo.BACKOFF_POLICY_LINEAR);
if (0 >= timerJob.schedule(builder.build()))
Feedback.postBackInfo("Job Build Error");
else Feedback.postBackInfo("Job Created and Scheduled");
}
where Feedback
and Utils
are other classes in my app which provide support services. To facilitate testing I am using a relatively small period of 30 seconds.
When I install and start the app the plugin init code calls launchTimerJob()
and I get the "Job Created and Scheduled" notification back as expected.
From that point forward I had expected to get Handled It! notifications from Handler
above at intervals of roughly 30s. A notification has turned up on the odd occasion but a totally arbitrary time measuring from App startup and has not obliged by repeating. Clearly, I am doing something wrong here.
Android docs could do a better job of mentioning that the minimum interval allowed for periodic jobs is 900,000 milliseconds, i.e.
15 minutes !!!!
I gather that prior to API 24 (Nogat) it was possible to use smaller intervals but no longer. Be wary of the various JobScheduler tutorials you will find out there. There are many that are quite dated and Android Jobs appears to be a still evolving API.
My own reason for originally using AlarmManager
was to enable background tasks to be performed when the app was, well, backgrounded. However, with the coming of doze mode this strategy fails since the app will simply not get broadcast messages when the device is dozing.
Consider the following strategy instead