Здравствуйте, как запустить службу в фоне, что бы после закрытия приложения (когда в списке активных приложений закрыл его) она продолжила работать? Например, как Вконтакте или любом другом мессенджере - приложения нет в списке активных приложений, но уведомления все равно продолжают приходить (лайки, новые сообщения).
Сейчас использую JobScheduler и запускаю с параметром setMinimumLatency (после того как задача выполнилась - вызываю опять создание задачи. На Android O минимальное время для повторения - 15 минут, для тестов использую 30 секунд). Если приложение открыто или висит в фоне, то служба работает. Если приложение закрыть, функция работать перестает. Я пытался выполнять код и в основном и в отдельном потоке, используя new Thread(new Runnable() в onStartJob
Вот пример используемого кода:
package com.example.sentike.myapplication;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.util.Log;
public class ExampleJobService extends JobService {
private static final String TAG = "ExampleJobService";
private boolean jobCancelled = false;
public static void StartService(Context InContext, Class<?> InServiceClass, long InIntervalInSeconds)
{
Log.debug( String.format("[AbstractNotifyPoolService][StartService][InServiceClass: %s / %d]", InServiceClass.getSimpleName(), InServiceClass.hashCode()));
try {
//=====================================================
long InIntervalInMs = InIntervalInSeconds * 1000;
Intent ServiceClassIntent = new Intent(InContext, InServiceClass);
//=====================================================
ComponentName ServiceComponentName = new ComponentName(InContext.getPackageName(), InServiceClass.getName());
//=====================================================
JobScheduler JobSchedulerService = (JobScheduler)InContext.getSystemService(Context.JOB_SCHEDULER_SERVICE);
//=====================================================
JobInfo.Builder JobServiceBuilder = new JobInfo.Builder(InServiceClass.hashCode(), ServiceComponentName)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setMinimumLatency(InIntervalInMs)
.setOverrideDeadline(TimeUnit.SECONDS.toMillis(5))
.setRequiresDeviceIdle(false)
.setRequiresCharging(false)
.setPersisted(true);
//=====================================================
int JobServiceScheduleStatus = JobSchedulerService.schedule(JobServiceBuilder.build());
if(JobServiceScheduleStatus == JobScheduler.RESULT_SUCCESS)
{
Log.debug( String.format("[AbstractNotifyPoolService][StartService][InServiceClass: %s][Successfully JobServiceSchedule]", InServiceClass.getSimpleName()));
}
else
{
Log.debug( String.format("[AbstractNotifyPoolService][StartService][InServiceClass: %s][Failed JobServiceSchedule]", InServiceClass.getSimpleName()));
}
}
catch (Exception e)
{
Log.debug( String.format("[AbstractNotifyPoolService][StartService][InServiceClass: %s][Exception: %s]", InServiceClass.getSimpleName(), e.getMessage()));
}
}
@Override
public boolean onStartJob(JobParameters params) {
Log.d(TAG, "Job started");
doBackgroundWork(params);
return true;
}
private void doBackgroundWork(final JobParameters params) {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
Log.d(TAG, "run: " + i);
if (jobCancelled) {
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.d(TAG, "Job finished");
jobFinished(params, false);
}
}).start();
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
}
@Override
public boolean onStopJob(JobParameters params) {
Log.d(TAG, "Job cancelled before completion");
jobCancelled = true;
return true;
}
}