Введение: вопрос, который проверяет уровень
«Что такое foreground service и чем он отличается от обычного Service?» — редкое собеседование по Android обходится без этого вопроса. И редкий кандидат отвечает на него полностью: про уведомление, типы и разрешения.
Foreground service — часть темы «Service», которую спрашивают на любом уровне: джуну достаточно не словить ANR в onStartCommand, мидлу нужно рассказать про ограничения фона, сеньору — про типы и разрешения Android 14. В моих разборах подготовки это одна из точек, где кандидаты с опытом 1–2 года теряют очки: все слышали слово, но мало кто может объяснить, зачем сервису уведомление и что изменилось в новых версиях Android.
Показательная деталь: ту же тему спрашивают «от обратного». Интервьюер говорит «представьте, что вам нужно писать трекер пробежек» — и кандидат должен сам назвать foreground service, перечислить требования и ограничения. Те, кто знает тему только понаслышке, отвечают «ну, можно же просто Service запустить в фоне» — и сразу теряют баллы, потому что на современном Android такой код даже не заработает.
Разберу по порядку: определение из документации, типы сервисов, код запуска и разрешения, о которых забывают.
Что такое foreground service: сервис, который видно
Формальное определение из официальной документации: foreground service — это сервис, который выполняет заметные пользователю операции и показывает уведомление в статус-баре, чтобы пользователь понимал, что приложение работает и потребляет ресурсы системы.
Ключевых отличия от обычного Service два:
- Постоянное уведомление. Сервис обязан показывать его с момента запуска до остановки. Спрятать уведомление нельзя — система этого не позволяет.
- Повышенный приоритет. Система реже убивает процесс с foreground service, чем процесс с обычным фоновым сервисом, и работа продолжается, даже когда приложение свёрнуто.
Как запомнить определение
Foreground service — это сервис, который «на глазах»: пользователь всегда видит уведомление о его работе. Всё, что происходит незаметно, — уже не его история.
Примеры из документации — музыкальный плеер, который показывает в уведомлении текущий трек, и фитнес-приложение, записывающее пробежку с дистанцией в уведомлении. Общее в обоих сценариях: пользователь не сидит в приложении, но работа должна продолжаться, и он должен об этом знать.
Частая ошибка на собеседовании: «foreground service нужен, чтобы выполнять работу в фоне незаметно». Наоборот — это сервис, который пользователь обязан видеть. Если задача незаметная, ей нужен другой инструмент.
Типы foreground service: обязательное требование Android 14
До Android 13 сервису было достаточно запуститься с уведомлением. Начиная с Android 14 (API 34) правила ужесточились: каждому foreground service нужно объявить тип — и в манифесте, и при вызове startForeground().
Тип задаётся атрибутом android:foregroundServiceType и описывает, чем занимается сервис. Основные типы из списка в документации:
dataSync— передача данных;mediaPlayback— воспроизведение медиа;location— геолокация;camera— доступ к камере;microphone— доступ к микрофону;connectedDevice— работа с подключёнными устройствами (BLE и другие).
Типов foreground service
dataSync, mediaPlayback, location, camera, microphone, connectedDevice, phoneCall, mediaProjection, health, remoteMessaging, systemExempted, specialUse — у каждого свои требования по разрешениям.
Приложение, таргетящее Android 14, без типа у сервиса получит MissingForegroundServiceTypeException при вызове startForeground(). А если тип указан, но в манифесте нет разрешения FOREGROUND_SERVICE_<ТИП> — SecurityException. Обе ошибки — классика крэш-репортов после обновления таргета.
Разрешения вида FOREGROUND_SERVICE_CAMERA, FOREGROUND_SERVICE_LOCATION и другие — normal: они выдаются автоматически, но объявлять их в манифесте обязательно. Правила Android 14 подробно описаны в документации об изменениях.
Как запустить foreground service: манифест и код
Покажу минимальный рабочий набор на примере сервиса с типом location. Сначала манифест:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application>
<service
android:name=".LocationTrackingService"
android:exported="false"
android:foregroundServiceType="location" />
</application>Теперь сам сервис. С Android 8 (API 26) уведомление обязано жить в канале (NotificationChannel):
class LocationTrackingService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
startForeground(NOTIFICATION_ID, buildNotification())
// ... запускаем трекинг
return START_STICKY
}
private fun buildNotification(): Notification {
val channel = NotificationChannel(
CHANNEL_ID, "Трекинг", NotificationManager.IMPORTANCE_LOW
)
getSystemService(NotificationManager::class.java)
.createNotificationChannel(channel)
return NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Идёт запись маршрута")
.setSmallIcon(R.drawable.ic_tracking)
.setOngoing(true)
.build()
}
override fun onBind(intent: Intent?): IBinder? = null
companion object {
private const val NOTIFICATION_ID = 42
private const val CHANNEL_ID = "tracking"
}
}Запуск на Android 8+ — только через ContextCompat.startForegroundService():
val intent = Intent(this, LocationTrackingService::class.java)
ContextCompat.startForegroundService(this, intent)А если поддерживаете Android 14 и хотите передать тип при запуске — используйте ServiceCompat.startForeground() из androidx.core 1.12+:
ServiceCompat.startForeground(
this,
NOTIFICATION_ID,
buildNotification(),
ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION
)Порядок действий важен: runtime-разрешения (например, ACCESS_FINE_LOCATION) должны быть выданы до вызова startForeground(). Система проверяет это и для некоторых типов просто не даст запустить сервис без разрешения.
Ограничения Android 8, 13 и 14: где сервис не запустится
Модель фоновой работы ужесточалась трижды, и на собеседовании выгодно показать, что вы видите всю картину:
- Android 8 (API 26) — приложение в фоне не может запустить обычный сервис через
startService(). Только foreground service — и только черезContextCompat.startForegroundService(). - Android 13 (API 33) — на показ уведомлений, включая уведомления сервисов, нужно runtime-разрешение
POST_NOTIFICATIONS. Если пользователь отказал — заметки о foreground service он видит в Task Manager, но не в шторке уведомлений (разрешение на уведомления). - Android 14 (API 34) — обязателен тип сервиса и
FOREGROUND_SERVICE_*в манифесте, а для типовcameraиlocation— ещё и runtime-разрешения. Сервис с типомcameraнельзя запустить из фона и изBOOT_COMPLETED-ресивера.
Отдельно про запуск из фона: начиная с Android 12 система серьёзно ограничила старт foreground service из фонового процесса — обычно это возможно только в коротком окне после ухода приложения в фон и в ряде исключений. Классическое правило, которое нужно озвучить на собеседовании: запускайте сервис по действию пользователя, а не «на всякий случай».
Ещё одна тема, которую любят проверять, — таймауты. Начиная с Android 15 для сервисов типа dataSync (и нового типа mediaProcessing) введён лимит: суммарно 6 часов работы за сутки, после чего система вызывает Service.onTimeout() — и у сервиса есть несколько секунд, чтобы вызвать stopSelf(). Если этого не сделать, система завершит сервис с ошибкой. Для собеседования достаточно знать, что механика есть, и упомянуть, что длительные задачи лучше раскладывать на этапы, а не держать один сервис вечно.
Когда foreground service не нужен
Главный вопрос, который ловит кандидатов: «А нельзя ли было обойтись без сервиса?» В документации прямо сказано: для многих сценариев существуют специальные API, и они почти всегда лучше собственного foreground service.
- Отложенная задача, которая должна пережить перезагрузку — WorkManager, а не сервис.
- Аудио и видео — Media3 / ExoPlayer уже умеют фоновое воспроизведение с уведомлением.
- Короткая работа при открытом приложении — корутины в
ViewModel, сервис не нужен вовсе. - Работа, которую пользователь видит и контролирует — вот здесь foreground service оправдан.
Лакмусовая бумажка
Задайте себе вопрос: «Поймёт ли пользователь, что приложение работает, если увидит уведомление?» Нет — ищем другой инструмент. Да — foreground service оправдан.
Готовитесь к собеседованию по Android?
Каждый второй кандидат теряет очки именно на теме фоновой работы: путает Service и Thread, не знает ограничений Android 14, не может объяснить, зачем сервису уведомление. Пришлю бесплатный чек-лист подготовки к собеседованию — конкретные пункты, что закрыть и в каком порядке.
Итоги
Foreground service — один из немногих компонентов, правила работы с которым менялись трижды за последние годы, поэтому тема отлично фильтрует кандидатов.
- Определение: foreground service — сервис с постоянным уведомлением, выполняющий заметную пользователю работу.
- Android 14: каждому сервису нужен тип в манифесте и разрешение
FOREGROUND_SERVICE_<ТИП>, иначеMissingForegroundServiceTypeExceptionилиSecurityException. - Современные ограничения: запуск по действию пользователя, runtime-разрешения до
startForeground(), а для простых задач — WorkManager или корутины.
Ответ, который закрывает тему
«Foreground service — это сервис с постоянно видимым уведомлением. На Android 14 у каждого сервиса должен быть тип и соответствующее разрешение, а runtime-разрешения выдаются до запуска. Если задача не требует видимого уведомления — это WorkManager или корутина».
Если чувствуете, что тема фоновой работы плавает, а собеседование уже скоро, — не нужно зубрить дальше в одиночку. Напишите в Telegram, разберём вашу ситуацию и составим план подготовки.