Служба планировщика заданий не работает, когда приложение отключено

#android #android-service

#Android #android-сервис

Вопрос:

Я работаю над приложением для Android, которое требует выполнения фоновой задачи каждый час (планировщик заданий или служба). Задача выполняется при запуске приложения, но как только я отключаю приложение с переднего плана, служба не работает. Есть ли другой способ добиться этого?

1. Служба

 public class NotificationService extends JobService {

    private void PrintLog()
    {
        Log.d("DGVCL", "PrintLog()");
    }

    @Override
    public boolean onStartJob(JobParameters jobParameters) {
        Log.d("DGVCL", "onStartJob()");
        PrintLog();
        jobFinished(jobParameters, false);
        return true;
    }

    @Override
    public boolean onStopJob(JobParameters jobParameters) {
        Log.d("DGVCL", "onStopJob()");
        return true;
    }
}
  

2. Основное действие

 JobScheduler jobScheduler = (JobScheduler)getApplicationContext().getSystemService(JOB_SCHEDULER_SERVICE);
        ComponentName componentName = new ComponentName(this, NotificationService.class);
        JobInfo jobInfo = new JobInfo.Builder(1, componentName)
                .setPeriodic(Global.NOTIFICATION_TIME_PERIOD)
                .setBackoffCriteria(Global.NOTIFICATION_TIME_PERIOD, JobInfo.BACKOFF_POLICY_LINEAR)
                .setPersisted(true).build();
        jobScheduler.schedule(jobInfo);
  

3. манифест

 <service android:name="com.hopesndreams.hiren.hd.service.NotificationService" android:permission="android.permission.BIND_JOB_SERVICE" >
    </service> 
  

Комментарии:

1. используйте work manager, теперь он стабилен и его лучше

2. в соответствии с последней версией Android вы можете запускать только службу переднего плана

3. На каком устройстве вы тестировали?

4. @hirenpatel не спрашивайте, могут ли люди предоставить примеры, прежде чем читать первыми. developer.android.com/guide/background

5. @hirenpatel В этом проблема, с которой вы используете Xiaomi, у меня xiaomi mi 6, и у меня такие же проблемы с WorkManager и JobSchedular, единственное, что работает после отключения приложения, — это AlarmManager

Ответ №1:

Используйте WorkManager, он построен поверх JobScheduler и специально создан для использования всех фоновых служб, как на переднем плане, так и в фоновом режиме. https://developer.android.com/topic/libraries/architecture/workmanager

Комментарии:

1. Несмотря на то, что Google обещает обрабатывать все запланированные задачи с помощью work Manager, я могу с уверенностью сказать, что это зависит от производителя устройства, например, на моем устройстве xioami work manager не будет работать после отключения приложения, на других телефонах оно работает.

2. @MaksimNovikov Какое решение будет лучшим, которое удовлетворит все потребности вне устройства?

3. Единственное, что я знаю, что все еще отлично работает на всех устройствах, — это старый и добрый AlarmManager

4. ^ обратите внимание, что запланированные сигналы тревоги удаляются при перезагрузке устройства

5. @SureshPeriyasamy вы придумали какое-нибудь решение? поскольку я все еще застрял, и у меня ничего не работает.

Ответ №2:

* Использование AlarmManager*

Шаг 1: Создайте службу

Выполняйте свою логику здесь, в службе

         public class AService extends Service {

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            //do something
        }

        @Override
        public void onCreate() {
            //do somrthing
        }
    }
  

Шаг 2: Создайте широковещательный приемник

Запустите свой сервис с этого.

         public class AReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                Intent intent = new Intent(context, AService.class);
                context.startService(intent);
            } catch (Exception e) {
            }
        }
    }
  

в MainActivity

    Intent liveIntent = new Intent(getApplicationContext(), AReceiver.class);
    PendingIntent recurring = PendingIntent.getBroadcast(getApplicationContext(), 0, liveIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Calendar updateTime = Calendar.getInstance();
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(), 16 * 60 * 1000, recurring);
    //wakeup and starts service in every 16 minutes.
  

У меня этот метод работает. Работает нормально, даже если вы закроете приложение. Работает на устройствах Xiaomi.

Не забудьте добавить службу в манифест

Комментарии:

1. Будьте осторожны, потому что сигналы AlarmManager стираются, если вы выключаете свой телефон

Ответ №3:

Действительно, WorkManager — это правильный путь.

Вы можете прочитать больше о других рабочих примитивах, подходящих для вашей задачи, здесь, но приведенная ниже реализация использует Worker для обработки потоков в WorkManager, который выполняет работу синхронно с фоновым потоком.

 public class BackgroundWorker extends Worker {

    public BackgroundWorker
            (@NonNull Context context,
             @NonNull WorkerParameters params) {
             super(context, params);
    }

    @NonNull
    @Override

    public Worker.Result doWork() {     
        yourBackgroundTask();  // yourBackgroundTask() implementation
        return Result.success();
    }

    public static void schedulePeriodicWork(Data data) {
        // When multiple constraints are specified like below, 
        // your task will run only when all the constraints are met.
        Constraints constraints = new Constraints.Builder()
                        .setRequiredNetworkType(NetworkType.CONNECTED)
                        .setRequiresBatteryNotLow(true)
                        .setRequiresCharging(true)
                        .build();

        PeriodicWorkRequest taskWork = new PeriodicWorkRequest.Builder(BackgroundWorker.class, 60,
                TimeUnit.MINUTES)
                .setConstraints(constraints)
                .setInputData(data)
                .build();

        WorkManager.getInstance().enqueue(taskWork);
    } 
}
  

Позже в вашем файле MainActivity, внутри onCreate() :

 Data data = workData();

BackgroundWorker.schedulePeriodicWork(data);
  

Затем вне onCreate() метода,

 private Data workData() {
    return new Data.Builder() // to build Data objects
        .build();
}
  

Следует отметить одну маленькую вещь: хотя мы настроили выполнение вышеупомянутой задачи каждые 60 минут, каждая итерация может выполняться не в один и тот же интервал времени.

Согласно документации Android, WorkManager предназначен для отложенной работы, и некоторые отклонения должны допускаться. Тем не менее, вы можете проверить свою консоль журнала на наличие обновления, « WM-WorkerWrapper: Worker result SUCCESS for Work «.

Надеюсь, это полезно.

Комментарии:

1. Я пытаюсь использовать это, но метод dowork вызывается только один раз. для тестирования я установил периодическое время в 20 секунд, но это не работает.

2. минимум 15 минут