How should i migrate my app to use JobScheduler?

Viewed 960

My app uses this classic pattern to schedule periodic tasks:

  1. Set an exact alarm via AlarmManager (via setExactAndAllowWhileIdle(), since it has to go off even in Doze)
  2. Start an IntentService from onReceive() via WakefulBroadcastReceiver.startWakefulService()
  3. Do the work in onHandleIntent() and call WakefulBroadcastReceiver.completeWakefulIntent() when finished.

Today i updated the targetSdkVersion to 26 and faced the terrible fact that WakefulBroadcastReceiver is deprecated.

I went to read API docs immediately and found the following:

As of Android O, background check restrictions make this class no longer generally useful. (It is generally not safe to start a service from the receipt of a broadcast, because you don't have any guarantees that your app is in the foreground at this point and thus allowed to do so.) Instead, developers should use android.app.job.JobScheduler to schedule a job, and this does not require that the app hold a wake lock while doing so (the system will take care of holding a wake lock for the job).

This is kinda confusing to me, i don't really understand what is the purpose of AlarmManager.setExactAndAllowWhileIdle() without being able to keep the device awake anymore.

As i see i cannot set an exact time to run a job with JobScheduler, only conditions (such as network type or charging state) so i have no idea what to do here.

I thought of either

  • Using AlarmManager and JobScheduler together

    Set an alarm (with setExactAndAllowWhileIdle()) and start a job (via JobScheduler) immediately from onReceive(). Since JobScheduler provides a WakeLock, WakefulBroadcastReceiver is not needed.

    (does this make sense?)

or

  • Keep using WakefulBroadcastReceiver despite being deprecated.

I'd really appreciate any advice on this matter.

2 Answers

You can use a BroadcastReciever that is triggered by your Alarm and in that receiver call JobIntentService.enqueueWork with your service, that you'll need to convert to a JobIntentService and implement the onHandleWork method.
The solution is described here:
Issue Moving from IntentService to JobIntentService for Android O

Related