#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 минут