Некоторые операции в приложении должны продолжаться, даже когда пользователь сворачивает его: музыкальный плеер, фитнес-трекер или загрузка файла. Обычный код в Activity для этого не подходит, потому что система может закрыть экран в любой момент. В Android для таких задач существует Foreground Service — служба, которая работает в фоне и обязательно показывает постоянное уведомление, чтобы пользователь знал о её активности. Этот урок поможет вам создать свою первую службу в Android Studio на языке Kotlin.
Зачем нужен Foreground Service
Фоновые службы без уведомления система может убить в любой момент, особенно при нехватке памяти. Foreground Service — это служба, которая считается приоритетной, потому что она связана с видимым уведомлением. Пока уведомление висит в шторке, система старается не останавливать службу. Это стандартный подход для плееров, навигаторов, звонков через интернет и других задач, которые требуют длительного выполнения.
Начиная с Android 8.0 (API 26), фоновые Service были сильно ограничены, и Google рекомендует использовать Foreground Service только для операций, которые пользователь явно запустил и ожидает, что они будут работать. В нашем примере мы сделаем простую службу, которая просто висит в фоне и показывает уведомление. Этого достаточно, чтобы понять принцип.
Регистрация службы в манифесте
Как и любой компонент, службу нужно объявить в AndroidManifest.xml внутри тега <application>. Для Android 8 и выше также нужно разрешение FOREGROUND_SERVICE, а для версий 14 и выше — FOREGROUND_SERVICE_MEDIA_PLAYBACK или другой тип в зависимости от задачи. Мы укажем общее разрешение FOREGROUND_SERVICE, а для запуска с уведомлением о простом действии достаточно этого.
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application ...>
<service
android:name=".MyForegroundService"
android:exported="false" />
</application>
</manifest>
Разрешение POST_NOTIFICATIONS необходимо для показа уведомлений на Android 13 (API 33) и выше. Его нужно запросить у пользователя во время выполнения, но для простоты можно временно отключить проверку в настройках или добавить запрос отдельно.
Создание канала уведомлений
Уведомление в Foreground Service отображается через NotificationManager. Для Android 8 и выше необходимо создать канал уведомлений. Это делается в onCreate службы. Создадим канал с понятным названием.
private fun createNotificationChannel() {
val channel = NotificationChannel(
CHANNEL_ID,
"Служба в фоне",
NotificationManager.IMPORTANCE_LOW
)
val manager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(channel)
}
Класс Foreground Service
Создайте класс, наследующий Service. В методе onStartCommand постройте уведомление и вызовите startForeground(). Этот вызов обязателен, иначе служба будет считаться фоновой и может быть убита. Также переопределим onBind, возвращая null — служба не привязана к компонентам.
class MyForegroundService : Service() {
companion object {
const val CHANNEL_ID = "foreground_service_channel"
}
override fun onCreate() {
super.onCreate()
createNotificationChannel()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(android.R.drawable.ic_dialog_info)
.setContentTitle("Служба запущена")
.setContentText("Работаю в фоне")
.setPriority(NotificationCompat.PRIORITY_LOW)
.build()
startForeground(1, notification)
return START_STICKY
}
override fun onBind(intent: Intent?): IBinder? = null
override fun onDestroy() {
super.onDestroy()
// можно добавить очистку ресурсов
}
}
Метод startForeground принимает уникальный идентификатор уведомления и само уведомление. С этого момента служба считается активной в фоне. Если уведомление убрать, служба может быть остановлена системой.
Запуск и остановка службы из Activity
В основной Activity добавьте две кнопки: «Запустить» и «Остановить». При запуске создаём Intent на нашу службу и вызываем startService(). Для остановки — stopService(). Начиная с Android 8, служба не может быть запущена, если приложение находится в фоне, поэтому вызов startService из Activity безопасен.
val btnStart = findViewById<Button>(R.id.btnStart)
val btnStop = findViewById<Button>(R.id.btnStop)
btnStart.setOnClickListener {
val intent = Intent(this, MyForegroundService::class.java)
startService(intent)
}
btnStop.setOnClickListener {
val intent = Intent(this, MyForegroundService::class.java)
stopService(intent)
}
Что важно помнить
- Всегда показывайте уведомление. Без вызова
startForeground()в течение 5 секунд после запуска система выбросит исключение и остановит службу. - Проверяйте версии Android. Для Android 13+ необходимо запросить
POST_NOTIFICATIONS, иначе уведомление не появится, но служба продолжит работать. - Останавливайте службу вовремя. Если служба больше не нужна, вызовите
stopSelf()илиstopService(), чтобы не расходовать батарею.
Подводя итог
Теперь вы умеете создавать простую фоновую службу с уведомлением в Android Studio. Это основа для более сложных приложений: плееров, трекеров, загрузчиков. Вы разобрались с регистрацией службы, созданием канала уведомлений и управлением жизненным циклом. Попробуйте расширить пример: добавьте кнопку в уведомление, которая останавливает службу прямо из шторки. Это отличное упражнение для закрепления материала.