如何使用 JobScheduler 为 Android 周期性作业指定初始延迟?

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

我想创建一个具有特定时间和给定周期的 运行ning 作业。例如,我想在每个月的第二天安排一个工作,它应该每个月 运行。

查看 JobInfo.Builder documentation 我还没有找到设置初始延迟的方法。

知道如何实现这一点吗?

这是 运行 具有正确周期但不是我想要的初始延迟的代码:

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())

您不能为定期作业应用初始延迟。目前应该可以使用一次性作业作为初始延迟,然后安排具有周期性间隔的新周期性作业。

从API 24开始,可以使用setPeriodic(long interval, long flex) 保证您的工作将 运行 在 flex 和提供的间隔之间的任何时间:

see documentation

您可以尝试查看以下实现

https://github.com/evernote/android-job/blob/master/library/src/main/java/com/evernote/android/job/DailyJob.java

的确,没有开箱即用的方法。我使用 SharedPreferences 来检测第一个作业 运行。示例:

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();
    }
}