Android Studio: урок Kotlin — Foreground Service с уведомлением

Некоторые операции в приложении должны продолжаться, даже когда пользователь сворачивает его: музыкальный плеер, фитнес-трекер или загрузка файла. Обычный код в 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. Это основа для более сложных приложений: плееров, трекеров, загрузчиков. Вы разобрались с регистрацией службы, созданием канала уведомлений и управлением жизненным циклом. Попробуйте расширить пример: добавьте кнопку в уведомление, которая останавливает службу прямо из шторки. Это отличное упражнение для закрепления материала.

Яндекс.Метрика