← Назад к вопросам

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

2.0 Middle🔥 192 комментариев
#Android компоненты#Жизненный цикл и навигация#Производительность и оптимизация

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Для запуска сервиса в новых версиях Android

Начиная с Android 8.0 (API level 26), введены существенные ограничения на выполнение фоновых операций, включая сервисы. Без объявления в манифесте (AndroidManifest.xml) и без явного запуска через startService() или startForegroundService(), сервис не запустится даже в более старых версиях. Однако, это базовые требования. С фокусом на новые версии (Android 8.0 и выше), ключевым является разделение на фоновые и видимые пользователю сервисы.

Обязательные условия для запуска

  1. Объявление в AndroidManifest.xml
    Каждый сервис должен быть явно объявлен в манифесте с тегом `<service>`. Используйте разрешения (например, `android:foregroundServiceType`) для определенных типов сервисов (звонки, локация и т.д.).

```xml
<service
    android:name=".MyForegroundService"
    android:enabled="true"
    android:exported="false"
    android:foregroundServiceType="location" <!-- Например, для сервиса, использующего геолокацию -->
/>
```

2. Запуск из подходящего контекста

    Сервис должен быть запущен из **видимого пользователю контекста** (например, `Activity`) или из другого компонента, который в данный момент имеет право запускать фоновые операции (например, **BroadcastReceiver**, получивший явный интент).

  1. Ключевое отличие для новых версий: Foreground Service
    Начиная с Android 8.0, если ваше приложение находится в **фоне** (пользователь не взаимодействует с ним), стандартный **фоновый сервис (background service) будет остановлен системой почти сразу после создания**. Поэтому для выполнения длительной работы необходимо использовать **Сервис на переднем плане (Foreground Service)**.

    **Без перевода сервиса в состояние "на переднем плане" в течение короткого таймаута** (несколько секунд для `startForegroundService()`, около минуты для `startService()` в некоторых случаях), система "убьет" сервис, и приложение получит **ANR (Application Not Responding)** или `IllegalStateException`.

Алгоритм корректного запуска (Android 8.0+)

Вот правильная последовательность действий для запуска долгоживущего сервиса:

  1. Используйте startForegroundService() (для Android 8.0+) или startService() (для более ранних версий) с проверкой версии.

    val serviceIntent = Intent(context, MyForegroundService::class.java)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        context.startForegroundService(serviceIntent)
    } else {
        context.startService(serviceIntent)
    }
    
  2. Немедленно в методе onCreate() или onStartCommand() сервиса вызовите startForeground(). Это самое критичное требование для новых версий.

    class MyForegroundService : Service() {
        private val NOTIFICATION_ID = 12345
        private val CHANNEL_ID = "ForegroundServiceChannel"
    
        override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
            createNotificationChannel()
            val notification = NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("Мой сервис")
                .setContentText("Работает на переднем плане")
                .setSmallIcon(R.drawable.ic_notification)
                .build()
            
            // ОБЯЗАТЕЛЬНЫЙ ВЫЗОВ! Без него сервис упадет в Android 8.0+.
            startForeground(NOTIFICATION_ID, notification)
            
            // Ваша фоновая логика здесь
            doWork()
            
            return START_STICKY
        }
        
        private fun createNotificationChannel() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val channel = NotificationChannel(
                    CHANNEL_ID,
                    "Foreground Service Channel",
                    NotificationManager.IMPORTANCE_LOW
                )
                val manager = getSystemService(NotificationManager::class.java)
                manager.createNotificationChannel(channel)
            }
        }
    }
    

Требования к объявлению Foreground Service (Android 9+ и 10+)

  • Android 9 (API level 28): Требуется разрешение FOREGROUND_SERVICE в манифесте. Без него вызов startForeground() выбросит исключение SecurityException.
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    
  • Android 10 (API level 29) и выше: Для доступа к камере или микрофону в фоновом режиме из сервиса на переднем плане требуется дополнительное разрешение:
    *   `android.permission.CAMERA` (и опция `android:foregroundServiceType="camera"` в объявлении сервиса)
    *   `android.permission.RECORD_AUDIO` (и опция `android:foregroundServiceType="microphone"`)

Исключения (когда можно без Foreground Service)

Даже в новых версиях есть сценарии, где сервис может работать без немедленного перевода на передний план:

  • Сервис, привязанный (Bound Service): Если сервис создается только через bindService() (без вызова startService()) и используется, пока хотя бы один клиент привязан, он считается частью вызывающего процесса. Однако, как только все клиенты отвяжутся, сервис будет уничтожен.
  • Сервис, запущенный из видимой активности или окна: Если сервис запущен из Activity, которая видна пользователю, система может позволить ему работать немного дольше.
  • Сервисы с высоким приоритетом: Например, сервисы, обрабатывающие входящие звонки (ConnectionService) или воспроизведение медиа (MediaSession), управляются особыми правилами.

Итог: В современных версиях Android (8.0+) без объявления, правильного запуска из подходящего контекста и, в большинстве случаев, без немедленного вызова startForeground() с созданием постоянного уведомления, сервис либо не запустится, либо будет сразу остановлен системой для оптимизации энергопотребления и производительности. Это часть политики Restrictions on background execution, которую каждый разработчик обязан учитывать.