Без чего не запустится сервис в новых версиях Android

Ответ

Сервис не запустится без явного объявления в манифесте (AndroidManifest.xml). Начиная с Android 8.0 (API 26), для сервисов также требуется:

  1. Явное указание foregroundServiceType (если сервис foreground)
  2. Запуск через startForegroundService() с последующим вызовом startForeground() в течение 5 секунд
  3. Разрешение FOREGROUND_SERVICE в манифесте

Пример для foreground сервиса:

<service 
    android:name=".MyService"
    android:foregroundServiceType="location|camera" />
startForegroundService(Intent(this, MyService::class.java))

Для background сервисов на Android 9+ есть ограничения - они могут быть запущены только приложением на переднем плане.

Ответ 18+ 🔞

А, слушай, вот реально история, которая у половины разработчиков волосы дыбом ставит. Ты пишешь сервис, всё вроде по учебнику, а он — раз! — и не запускается. И стоишь такой, смотришь в логкат, а там нихуя. Тишина. И думаешь: «Ну что я опять забыл, ёпта?»

А забыл ты, голубчик, про манифест. Это как паспорт для приложения. Без явной прописки в AndroidManifest.xml твой сервис — это просто беспаспортный бомж, которого система на порог не пустит. Совсем.

Но это ещё цветочки. Начиная с Android 8.0 (это API 26, если ты вдруг забыл, какой у нас год на дворе — как будто 2002-й, только сложнее), начался ёперный театр.

Если твой сервис должен работать, когда пользователь в другом приложении (то есть foreground сервис), то тебе нужно:

  1. Явно указать foregroundServiceType. Это как объяснить системе: «Слушай, я не просто так батарейку сажу, я, блядь, локацию отслеживаю или камеру использую!» Пишешь в манифесте:

    <service 
        android:name=".MyService"
        android:foregroundServiceType="location|camera" />

    Без этого — получишь SecurityException и волнение ебать.

  2. Запускать через startForegroundService(). Не через старый добрый startService(), а именно через этот метод. Он системе сигнализирует: «Внимание, щас будет foreground-сервис!»

    startForegroundService(Intent(this, MyService::class.java))
  3. И БЫСТРО, БЛЯДЬ, В ТЕЧЕНИЕ 5 СЕКУНД вызвать startForeground(). Это самый частый косяк. Ты вызвал startForegroundService(), а в самом сервисе забил хуй на startForeground(). Система тебе даёт 5 секунд на раскачку, а потом — бац! — ANR (Application Not Responding) и приложение накрывается медным тазом. Внутри сервиса, в onCreate() или onStartCommand(), обязательно делай:

    startForeground(NOTIFICATION_ID, createNotification())

    Создай нормальное уведомление, чтобы пользователь видел, чё это у него в шторке висит.

  4. Разрешение FOREGROUND_SERVICE в манифесте. Мелочь, но без неё тоже может не взлететь. Просто добавь:

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

А что с background сервисами? С ними, чувак, вообще грусть. На Android 9 и выше, если твоё приложение не на переднем плане (не в foreground), то запустить background сервис ты не сможешь. Система тебе просто скажет: «Иди ты нахуй со своим фоновым кодом». Всё, приехали. Для долгих фоновых задач теперь нужно использовать WorkManager или JobScheduler. Это отдельная песня, про которую можно овердохуища говорить.

Короче, алгоритм такой: хотел сервис — проверь манифест. Хотел foreground — объяви тип, запускай правильно и не забудь про уведомление. Иначе будет тебе хиросима в логах, а не работающий код.