首页 > 解决方案 > 在准确的时间使用 Job Scheduler 执行后台任务

问题描述

我正在开发新闻应用程序。而且我需要每天获得一次最新消息。为此,我使用了 Jobsheduler。这是代码:

ComponentName componentName = new ComponentName(this, JobService.class);
        JobInfo jobInfo = new JobInfo.Builder(123, componentName)
                .setRequiresCharging(false)
                .setPeriodic(24 * 60 * 60 * 1000)
                .setPersisted(true)
                .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
                .build();
        JobScheduler jobScheduler = (JobScheduler)getApplicationContext().getSystemService(JOB_SCHEDULER_SERVICE);
        int resultCode = jobScheduler.schedule(jobInfo);

        if (resultCode == JobScheduler.RESULT_SUCCESS){
            Log.d(TAG, "Job Scheduled");
        }
        else {
            Log.d(TAG, "Job Scheduling failed");
        }

但现在我需要在早上 6:00 之后做一次这项工作,届时将有互联网连接。有没有办法用 Job Scheduler 做到这一点。我知道我可以使用警报管理器来做到这一点,但在有连接、设备充电等情况下,作业计划程序比警报管理器要好得多。或者,如果需要,我可以使用 Workmanager 来实现这一点,它使用 Job Scheduler 和 AlarmManager。或者还有其他方法吗???任何建议表示赞赏。

标签: androidalarmmanagerandroid-workmanagerandroid-jobscheduler

解决方案


public static final String CUSTOM_INTENT = "com.test.intent.action.ALARM";
public static Context ctx = OfferlyApplication.getContext();

@Override
public void onReceive(Context context, Intent intent) {
    /* enqueue the job */
    AlarmJobIntentService.enqueueWork(context, intent);
}
public static void cancelAlarm() {
    AlarmManager alarm = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);

    /* cancel any pending alarm */
    alarm.cancel(getPendingIntent());
}
public static void setAlarm(boolean force) {
    cancelAlarm();
    AlarmManager alarmManager = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
    // EVERY X MINUTES
    long delay = (1000 * 60 * 60);
    long when = System.currentTimeMillis();
    if (!force) {
        when += delay;
    }
    /* fire the broadcast */
    PendingIntent pendingIntent = getPendingIntent();
    int SDK_INT = Build.VERSION.SDK_INT;
    if (SDK_INT < Build.VERSION_CODES.KITKAT)
        alarmManager.set(AlarmManager.RTC_WAKEUP, when, pendingIntent);
    else if (SDK_INT < Build.VERSION_CODES.M)
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, when, pendingIntent);
    else {
        Log.d("JOB_SCHEDULING","waking device");
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, when, pendingIntent);
    }
}
private static PendingIntent getPendingIntent() {
    //Context ctx;   /* get the application context */
    Intent alarmIntent = new Intent(ctx, AlarmReceiver.class);
    alarmIntent.setAction(CUSTOM_INTENT);
    return PendingIntent.getBroadcast(ctx, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
}

或为定期工作人员使用工作管理器

 Constraints myConstraints = new Constraints.Builder()
            .setRequiresDeviceIdle(false)
            .setRequiresCharging(false)
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .setRequiresBatteryNotLow(true)
            .setRequiresStorageNotLow(true)
            .build();

    PeriodicWorkRequest saveRequest =
            new PeriodicWorkRequest.Builder(NotificationWorker.class, 60, TimeUnit.MINUTES)
                    .setConstraints(myConstraints)
                    .build();

    WorkManager.getInstance()
            .enqueue(saveRequest);

推荐阅读