Search code examples
androidalarmmanagerandroid-alarmsjob-schedulingandroid-api-levels

manage periodic tasks with job Scheduler?


Basically what I want to do is, when there is an internet connection then collect values from sensors and schedule the next time data is collected from sensors, let's say 5 minutes (this interval depends on the current activity: walking, running...). After 5 minutes, the system checks if there is internet connection:

-if there is then the cycle is repeated (collection, sending to server and scheduling the next data collection)

*if there isn't then the next time the data is collected is scheduled for the next time there is an available internet connection

What I tried using:

1) I wanted to use a broadcast receiver for api<21 and job scheduler for api>=21. For job scheduler, I can't set requirement available network and make the job periodic at the same time because this way the job runs after the period is over whether the requirement is met or not.

2)I tried to make the job service set the next job after the current one is over but the app ran as if that part of the code didn't exist (it only ran once)

3) I tried to somehow combine job scheduler with alarm manager to make the job scheduler manage the network requirement and the alarm manager manage the periodic aspect of the job. But I failed to implement this and I feel like this isn't the right way to do it.

If someone could guide me to a better way to handle this, I'd really appreciate it because I've spent a long time trying to solve this.


Solution

  • I would recommend a library from Evernote called android-job. It handles all the complexity of choosing JobScheduler on 21+, Firebase/GcmNetworkManager, or AlarmManager and all kinds of other things. It has a pretty robust set of features that should fit your use case.

    For Example:

    int jobId = new JobRequest.Builder(DemoSyncJob.TAG)
            .setExecutionWindow(30_000L, 40_000L)
            .setBackoffCriteria(5_000L, JobRequest.BackoffPolicy.EXPONENTIAL)
            .setRequiresCharging(true)
            .setRequiresDeviceIdle(false)
            .setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
            .setExtras(extras)
            .setRequirementsEnforced(true)
            .setPersisted(true)
            .setUpdateCurrent(true)
            .build()
            .schedule();