Периодическая задача планировщика заданий Android не работает через некоторое время или после перезагрузки устройства

Я пытаюсь выполнить периодическую задачу с помощью планировщика заданий. Я хочу вызывать службу каждые 10 секунд, она работает нормально в течение пары часов, но иногда перестает работать и не работает после перезагрузки устройства.

Вот что я пробовал

ComponentName getAlertJobComponent = new ComponentName(context.getPackageName(), GetAlertJobService.class.getName());
JobInfo.Builder getAlertbuilder = new JobInfo.Builder(Constants.getAlertJobid, getAlertJobComponent);
getAlertbuilder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); // require unmetered network
getAlertbuilder.setRequiresDeviceIdle(true); // device should be idle
getAlertbuilder.setPeriodic(10 * 1000);
getAlertbuilder.setRequiresCharging(false); // we don't care if the device is charging or not
JobScheduler getAlertjobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
getAlertjobScheduler.schedule(getAlertbuilder.build());

И моя работа

public class GetAlertJobService extends JobService {
    @Override
    public boolean onStartJob(JobParameters params) {

        if (!Utility.isServiceRunning(GetAlertService.class, getApplicationContext())) {
            startService(new Intent(getApplicationContext(), GetAlertService.class));
        }
        jobFinished(params, false);
        return true;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        return true;
    }
}

Здесь GetAlertService — это служба, которая вызывает веб-службу.

ИЗМЕНИТЬ

Я также добавил это в загрузочный приемник, как показано ниже.

 public class Boot extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                ComponentName getAlertJobComponent = new ComponentName(context.getPackageName(), GetAlertJobService.class.getName());
                JobInfo.Builder getAlertbuilder = new JobInfo.Builder(Constants.getAlertJobid, getAlertJobComponent);
                getAlertbuilder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); // require unmetered network
                getAlertbuilder.setRequiresDeviceIdle(true); // device should be idle
                getAlertbuilder.setPeriodic(10 * 1000);
                getAlertbuilder.setPersisted(true);
                getAlertbuilder.setRequiresCharging(false); // we don't care if the device is charging or not
                JobScheduler getAlertjobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
                getAlertjobScheduler.schedule(getAlertbuilder.build());
            }
        }
    }

в манифесте

<receiver
    android:name=".broadcastreceiver.Boot"
    android:enabled="true">

    <intent-filter android:priority="999">
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

person mSapps    schedule 30.01.2017    source источник


Ответы (1)


Проблема сброса решается путем добавления setPersisted(true) в построитель заданий. Ибо перестает работать спустя долгое время - аппарат спит? Если да, то, скорее всего, проблема с дозировкой.

person Gabe Sechan    schedule 30.01.2017
comment
да, устройство спит. Если да, то как я могу преодолеть это - person mSapps; 30.01.2017
comment
Вы не можете. JobScheduler не работает в режиме ожидания. Вы можете спуститься к AlarmManager и использовать setExactAndAllowWhileIdle, но это все равно не позволит вам просыпаться так часто, как вы хотите (минимальный период IIRC 2 минуты между тревогами и максимальное число, которое вы можете иметь в любые 15 минут период). - person Gabe Sechan; 30.01.2017
comment
На самом деле есть одна вещь, которую вы можете сделать — вы можете попросить пользователей отключить оптимизацию батареи для вашего приложения. Это в той ссылке, которую я разместил. - person Gabe Sechan; 30.01.2017
comment
Пожалуйста, проверьте мое редактирование. Я также добавил это в загрузочный приемник, это нормально? - person mSapps; 30.01.2017
comment
Режим @GabeSechan Doze понятен, но через пару часов, когда устройство просыпается, после этого оно все равно больше не работает. - person Sharp Edge; 06.02.2017
comment
@SharpEdge, да, и что нам с этим делать? - person Alexey Subbota; 16.03.2017
comment
@AlexeySubbota Я переключился на Firebase JobDispatcher для обратной совместимости. Пока что я отказаться от борьбы с режимами Doze или Battery Saver и показать пользователю сообщение, чтобы отключить его, если они хотят, чтобы определенная функция работала правильно. - person Sharp Edge; 16.03.2017
comment
@GabeSechan Вы не можете. JobScheduler не работает в режиме ожидания. В устройстве ожидания есть окна для выполнения некоторой необходимой работы, и пока окно открыто, JobService будет выполняться. - person LifeStyle; 19.12.2017
comment
@LifeStyle Да, каждые 15 минут или около того с экспоненциальным отставанием. Не каждые 10 секунд. - person Gabe Sechan; 19.12.2017