¿Se cayó el foreground service después de la actualización? No está solo
\nImagine: inicia su aplicación, debería funcionar en segundo plano mostrando una notificación importante. Todo funcionaba perfectamente en Android 7.0, los usuarios están contentos. Pero luego llega la actualización a Android 8.1 — y la aplicación falla con el misterioso error startForeground fail. ¿Le suena? Si se ha enfrentado a este problema, sabe lo desconcertante que puede ser. En Stack Overflow, esta pregunta ha acumulado miles de visitas, lo que significa que ha afectado a muchos desarrolladores. En este artículo, analizaremos por qué ocurre esto, cómo solucionar el error en Kotlin y, lo más importante, cómo evitarlo en el futuro.
¿Qué es startForeground y para qué sirve?
\nEn Android, un foreground service (servicio en primer plano) es un servicio que realiza acciones visibles para el usuario. Por ejemplo, reproducir música, grabar una ruta GPS o descargar un archivo. A diferencia de un servicio normal, un foreground service debe mostrar una notificación permanente en la barra de estado. Esto se hace mediante la llamada a startForeground(), que recibe un ID de notificación y el propio objeto Notification.
A partir de Android 8.0 (API 26), Google introdujo restricciones estrictas para los servicios en segundo plano. Ahora, si intenta iniciar un foreground service sin una notificación correctamente configurada, el sistema lanzará una excepción ForegroundServiceStartNotAllowedException o simplemente ignorará la llamada. En Android 8.1, estas restricciones se volvieron aún más estrictas, y el error startForeground fail se volvió masivo.
¿Por qué ocurre startForeground fail en Android 8.1?
\nLa razón principal es la falta o configuración incorrecta del canal de notificaciones (Notification Channel). Antes de Android 8.0, las notificaciones se podían crear sin canales. Después de la actualización, Google obligó a los desarrolladores a crear al menos un canal para cada tipo de notificación. Si llama a startForeground() con una notificación que no tiene canal, el sistema simplemente no sabe cómo mostrarla y lanza un error.
La segunda razón es la violación del tiempo de ejecución. Debe llamar a startForeground() dentro de los primeros 5 segundos después de iniciar el servicio. Si no lo hace, el servicio será eliminado y la aplicación podría fallar.
La tercera razón es el intento de iniciar el servicio desde segundo plano. A partir de Android 8.0, está prohibido iniciar un foreground service desde un contexto en segundo plano (por ejemplo, desde un BroadcastReceiver u otro servicio). La única excepción es si la aplicación está en primer plano.
\n\nCómo solucionarlo: guía paso a paso en Kotlin
\nReescribamos su servicio para que funcione en Android 8.1 y versiones posteriores. Usaremos Kotlin, un lenguaje moderno y conciso.
\n\nPaso 1: Cree el canal de notificaciones
\nEl canal debe crearse antes de mostrar la notificación. El mejor lugar es en el método onCreate() de su servicio o en la clase Application. Aquí tiene un ejemplo:
class MyForegroundService : Service() {\n companion object {\n const val CHANNEL_ID = "my_foreground_channel"\n const val NOTIFICATION_ID = 1\n }\n\n override fun onCreate() {\n super.onCreate()\n createNotificationChannel()\n }\n\n private fun createNotificationChannel() {\n if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n val channel = NotificationChannel(\n CHANNEL_ID,\n "Canal de Servicio en Primer Plano",\n NotificationManager.IMPORTANCE_LOW\n ).apply {\n description = "Canal para notificaciones del servicio en primer plano"\n }\n val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager\n notificationManager.createNotificationChannel(channel)\n }\n }\n}\nTenga en cuenta: verificamos la versión del SDK. En dispositivos antiguos, los canales no son necesarios, y