Выполнение фоновых задач с помощью планировщика заданий в точное время

Я работаю над приложением "Новости". И мне нужно было получать последние новости раз в день. Для этого я использовал 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, когда будет подключение к Интернету. Есть ли способ сделать это с помощью планировщика заданий. Я знаю, что могу сделать это с помощью диспетчера аварийных сигналов, но планировщик заданий намного лучше, чем диспетчер аварийных сигналов, в таких условиях, как наличие соединения или зарядка устройства. Или я могу добиться этого с помощью Workmanager, который при необходимости использует планировщик заданий и AlarmManager. Или есть другой способ сделать это ??? Любые предложения приветствуются.


person Whiteq    schedule 20.02.2020    source источник


Ответы (2)


Вы можете использовать широковещательный приемник вместе с диспетчером работ, который сообщит вам, что соединение доступно, и завершит запланированную задачу ИЛИ вы можете запускать Worker каждые 15 минут после 6:00 (минимальное время для 2 последовательных рабочих ) и проверьте, доступен ли интернет, и делайте свою работу

person Prakash Reddy    schedule 20.02.2020
comment
Могу ли я использовать диспетчер сигналов тревоги, чтобы запускать планировщик заданий каждое утро в 6:00? - person Whiteq; 20.02.2020
comment
Диспетчер сигналов тревоги не будет работать должным образом на устройствах Android 6+ из-за большего разряда батареи, поэтому вам нужно использовать широковещательный приемник + планировщик заданий, как показано ниже, где вы можете сделать, как указано выше. - person Prakash Reddy; 20.02.2020
comment
Да, вы можете использовать и запускать такой процесс как AlarmReceiver.setAlarm (true); / * true вызовет трансляцию * / - person Prakash Reddy; 20.02.2020

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);
person Prakash Reddy    schedule 20.02.2020
comment
здесь, в примере менеджера работы, как я могу установить точное время ??? Это возможно? - person Whiteq; 20.02.2020