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

7
我想创建一个定时任务,需要指定时间和周期。例如,我想安排一个任务在每个月的第二天,并且它应该每个月运行一次。
查看JobInfo.Builder文档,我没有找到设置初始延迟的方法。
你有什么想法吗?
以下是具有正确周期性但缺少我所需的初始延迟的代码:
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())

1
延迟只适用于第一次运行吗? - Willi Mentzel
你可以根据你的具体需求触发报警来执行作业。 - hemen
是的,延迟只适用于第一次运行。 - César Alberca
实际上,答案已经在你手中了。由于存在两种完全可接受的解决方法,因此初始延迟是不必要的:
  1. 您可以将“生效日期”指定为作业参数之一,并在每次作业唤醒时进行检查(不太优雅,但更简单)。
  2. 您可以推迟实际作业创建,并安排在“生效日期”时创建它的作业(更优雅,需要编写更多代码)。
- Max Alekseev
4个回答

1
您无法为周期性任务设置初始延迟。目前,您可以使用一次性任务进行初始延迟,然后使用周期间隔安排新的周期性任务。

1
是的,目前看来这似乎是唯一的解决方案。我只希望他们能包含一些更简单的延迟作业的方法。谢谢! - César Alberca
你有任何例子吗? - JCarlosR

1

事实上,没有逃出这个“盒子”的方法。我使用 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();
    }
}



-2
自API 24以来,可以使用setPeriodic(long interval, long flex)函数。保证您的作业将在flex和提供的间隔之间的任何时间运行:

请参阅文档


无法同时使用setPeriodic()和setMinimumLatency()。 - SoloPilot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接