Задать вопрос

Почему останавливается сервис в Android приложении?

Добры день! Я пишу Android приложение, которое должно выполнять некие длительные задачи в фоне (в том числе и когда само приложение свёрнуто). Для простоты будем считать, что длительная задача заключается в том, что раз в секунду увеличивается некий счётчик, и сервис отправляет уведомление, показывающее значение счётчика. Я прочитал, что для релизации подобных задач нужно использовать сервисы. Я реализовал сервис, унаследовал его от IntentService и описал в нём логику работы вместе с отправкой уведомлений пользователю. Проблема в том, что если выйти из приложения, то спустя некоторое время сервис остановится, и уведомления перестанут приходить. Гугление показало, что это довольно распространённая проблема, и она решается возвратом флага START_STICKY или START_REDELIVER_INTENT из метода onStartCommand (я пробовал оба флага). К сожалению этот способ мне не помог - сервис спустя какое-то время по-прежнему останавливается операционной системой. Код написан на C# (я использую xamarin), но надеюсь, что для людей пишущих на java там нет ничего непонятного. Код выглядит так:

public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
    base.OnStartCommand(intent, flags, startId);     
     
    var thread = new Thread(new Runnable(() => 
    {
        for (int i = 0; i < 10_000; i++)
        {
            ShowNotification("channel", "Search", $"second: {i}, threadId: {id} startId: {startId}");
            Thread.Sleep(1000);
        }                           
        StopSelf(startId);
    }));
    thread.Start();

    return StartCommandResult.StartSticky;
}


Метод ShowNotification выглядит так:

protected void ShowNotification(string channel, string title, string message)
{
    Intent resultIntent = new Intent(this, GetType());
    resultIntent.AddFlags(ActivityFlags.NewTask);

    var resultPendingIntent = PendingIntent.GetActivity(this, 0, resultIntent, PendingIntentFlags.UpdateCurrent);

    var mBuilder = new NotificationCompat.Builder(this);
    mBuilder.SetSmallIcon(Resource.Mipmap.ic_launcher)
        .SetContentTitle(title)
        .SetContentText(message)
        .SetAutoCancel(false)
        .SetContentIntent(resultPendingIntent);

    if (!(GetSystemService(NotificationService) is NotificationManager mNotificationManager))
        return;

    if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
    {
        var importance = NotificationImportance.High;
        var notificationChannel = new NotificationChannel(channel, channel, importance);
        notificationChannel.EnableLights(true);
        notificationChannel.LightColor = Color.Red;
        notificationChannel.EnableVibration(true);
        notificationChannel.SetVibrationPattern(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 });
        mBuilder.SetChannelId(channel);
        mNotificationManager.CreateNotificationChannel(notificationChannel);
    }
    mNotificationManager.Notify(0, mBuilder.Build());
}


Сервис работает некоторое время (иногда минуту, иногда пять), ежесекундно присылает уведомления, но если выйти из приложения, рано или поздно он прекращает работу, и новые уведомления больше не приходят. Может быть кто-то в курсе, как решить эту проблему и заставить сервис работать постоянно, до тех пор, пока пользователь не остановит его или он не закончит выполнение своей работы? Ну или как заставить сервис перезапускаться каждый раз после того, как ОС его остановила?
Насколько я понимаю, эта проблема решаема, ведь есть множество приложений, которые спокойно работают в фоновом режиме. Например торрент-клиенты, которые могут в течение нескольких часов скачивать какой-либо файл и выводить уведомления о прогрессе загрузки. Ну или музыкальные плееры, которые воспроизводят музыку в фоновом режиме, при этом музыка не прерывается (то есть сервис скорее всего не останавливается операционной системой).
Как это реализовано в других приложениях и в чём моя ошибка (ну кроме того, что я использую Xamarin, с этим уже сложно что-то поделать) ? Заранее спасибо!
  • Вопрос задан
  • 677 просмотров
Подписаться 3 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 1
402d
@402d
начинал с бейсика на УКНЦ в 1988
> Я реализовал сервис, унаследовал его от IntentService
Forget about using IntentService, it stops as the app stops because it runs on the same process as the app.
https://stackoverflow.com/questions/44114517/long-...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы