Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specify a initial delay to an Android periodic job using JobScheduler?

I want to create a running job with a specific time and a given periodicity. For example, I want to schedule a job the second day of each month and it should run every month.

Looking at the JobInfo.Builder documentation I haven't found a way to set an initial delay.

Any idea on how could I achieve this?

Here is the code that runs with the correct periodicity but not with the initial delay I want:

fun build(application: Application, periodicity: Days, startDay: Days) {
    val serviceComponent = ComponentName(application, GenerateDebtJobService::class.java)
    val builder = JobInfo.Builder(1, serviceComponent)
        .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
        .setPeriodic(TimeUnit.DAYS.toMillis(periodicity.days.toLong()))

    (application.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler).schedule(builder.build())
like image 299
César Alberca Avatar asked Jan 08 '18 11:01

César Alberca


2 Answers

You can't apply an initial delay for the periodic job. Currently should may use a one shot job for the initial delay and then schedule a new periodic job with the periodic interval.

like image 60
Ron____ Avatar answered Oct 01 '22 17:10

Ron____


Indeed, there is no way out of the box. I use SharedPreferences to detect the first job run. Example:

public class MyReminder extends JobService {
    private static final String TAG = "MyReminder";
    private static final String IS_FIRST_RUN_KEY = "MyReminder.isFirstRun";

    @Override
    public boolean onStartJob(JobParameters jobParameters) {
        if (isFirstRun()) {
            // just skip it, will mark as first run and 
            // will do the real thing next time
            markFirstRunComplete();
        } else {
            // do the real thing here, show a notification, whatever...
        }
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters jobParameters) {
        return false;
    }

    private boolean isFirstRun() {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        return sharedPreferences.getBoolean(IS_FIRST_RUN_KEY, true);
    }

    private void markFirstRunComplete() {
        Log.d(TAG, "mark first run complete");
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putBoolean(IS_FIRST_RUN_KEY, false);
        editor.apply();
    }
}

like image 33
iutinvg Avatar answered Oct 01 '22 17:10

iutinvg