Reputation: 703
What I want to implement is a background service that fetch data from the server every hour. I expect this service can run periodically after the boot. Thus, I choose to use JobScheduler to implement this function.
val jobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
val builder = JobInfo.Builder(1, ComponentName(this, PullDataJob::class.java))
.setPeriodic(1000L * 60 * 60) // one hour
.setRequiredNetworkType(NETWORK_TYPE_ANY)
.setPersisted(true)
jobScheduler.schedule(builder.build())
This is my currently code, which is placed inside onCreate()
. However, I find that if I put the JobScheduler.schedule()
in onCreate()
, the service will be automatically executed every time I open the application.
Where is the best place to put the code above to make the service run periodically even if the user never opens the application after system boot?
Upvotes: 3
Views: 1097
Reputation: 329
Hakeem is right, you should only schedule it once. In case you schedule a job with the same JobId twice, the documentation states following:
Will replace any currently scheduled job with the same ID with the new information in the JobInfo. If a job with the given ID is currently running, it will be stopped.
But i would solve the problem different to the way hakeem did. Instead of saving this information in a Sharedpreference you should use the JobScheduler to determine if the job with your id has been scheduled already. This way you are more robust and will reschedule the job in case some weird thing happened and your job is not scheduled anymore.
Code:
public static boolean isJobServiceOn( Context context ) {
JobScheduler scheduler = (JobScheduler) context.getSystemService( Context.JOB_SCHEDULER_SERVICE ) ;
boolean hasBeenScheduled = false ;
for ( JobInfo jobInfo : scheduler.getAllPendingJobs() ) {
if ( jobInfo.getId() == RETRIEVE_DATA_JOB_ID ) {
hasBeenScheduled = true ;
break ;
}
}
return hasBeenScheduled ;
}
When scheduling the Job you can then just use this function to determine if the job i currently scheduled or not.
Upvotes: 3
Reputation: 4570
Your job is executed periodically (once every hour), so once it's run the first time, JobScheduler.schedule()
should never be called again.
Accomplishing this is quite easy, once you call JobScheduler.schedule()
for the first time, register the fact that it's been scheduled, and only run the scheduling method when you're sure your job have never been run before.
public static final String IS_JOB_FIRST_RUN = "job scheduled";
...
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
if (preferences.getBoolean(IS_JOB_FIRST_RUN, true)) {
// your code
JobScheduler.schedule();
preferences.edit().putBoolean(IS_JOB_FIRST_RUN, false).apply();
}
Upvotes: 1