Soluciona problemas de servicios en primer plano

En esta página, se analizan algunos motivos comunes por los que pueden fallar los servicios en primer plano y se te ayuda a identificar la causa del problema.

En este documento, se analizan los siguientes problemas:

Antes de solucionar el problema, realiza lo siguiente:

Verifica si hay cambios recientes en los servicios en primer plano

Si los servicios en primer plano se usan de forma inadecuada, pueden tener efectos negativos en el rendimiento del dispositivo y la duración de la batería. Por este motivo, las versiones de la plataforma de Android suelen realizar cambios en el comportamiento de los servicios en primer plano para limitar estos efectos negativos.

Si tienes problemas con los servicios en primer plano, debes consultar la documentación sobre los cambios en los servicios en primer plano y ver si hay cambios recientes que puedan explicar tus problemas. Es especialmente importante verificar los cambios en las siguientes circunstancias:

  • El código del servicio en primer plano que antes funcionaba ahora falla.
  • Acabas de comenzar a realizar pruebas en una nueva versión de la plataforma o cambiaste el nivel de API al que se orienta tu app.

Además, si pruebas tu dispositivo en una versión preliminar para desarrolladores de la plataforma, asegúrate de consultar la versión más reciente de la documentación de la versión preliminar para desarrolladores.

Errores de tipo Aplicación no responde (ANR)

En determinadas circunstancias, se espera que una app apague su servicio en primer plano. Si la app no detiene el servicio, el sistema lo detiene y activa un error de Aplicación no responde (ANR).

El servicio de corta duración se ejecuta durante demasiado tiempo, lo que provoca un error de ANR

Los servicios en primer plano que usan el tipo de servicio de corta duración deben completarse rápidamente, en aproximadamente tres minutos. Cuando se agota el tiempo, el sistema llama al método Service.onTimeout(int,int) del servicio. El servicio tiene unos segundos para llamar a stopSelf(). Si el servicio no se detiene, el sistema activa un error de Aplicación no responde.

Diagnóstico:

Si el error de ANR se debió a que un servicio en primer plano no se detuvo, el sistema arroja una excepción interna. Para verificar que este fue el problema, consulta los informes de ANR. Si este es el problema, el informe incluirá el siguiente mensaje:

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type FOREGROUND_SERVICE_TYPE_SHORT_SERVICE did not stop within its timeout:
[component name]"

Solución:

Asegúrate de que todos los servicios en primer plano de corta duración finalicen su trabajo y llamen a stopForeground(int) dentro del límite de tiempo del sistema.

Haz que tus servicios en primer plano implementen Service.onTimeout(int,int). Asegúrate de que tu implementación de ese método llame a stopSelf() de inmediato.

Excepciones de servicios en primer plano

En esta sección, se describen varios problemas de servicios en primer plano que pueden hacer que el sistema arroje una excepción. Si la app no detecta la excepción, el usuario verá un diálogo que le indicará que la app se detuvo.

En algunos casos, el sistema arroja una excepción interna. En esos casos, puedes averiguar cuál fue la excepción consultando el seguimiento de pila y Logcat para obtener información más detallada sobre el error.

Excepción interna: Se excedió el tiempo de espera

El sistema impone un límite en el tiempo que pueden ejecutarse los servicios en primer plano de sincronización de datos y procesamiento de contenido multimedia mientras la app está en segundo plano. Si el servicio excede ese límite, el sistema llama al método Service.onTimeout(int,int) del servicio. El servicio tiene unos segundos para llamar a stopSelf(). Si el servicio no se detiene, el sistema genera una RemoteServiceException interna que hace que la app falle.

Diagnóstico:

Puedes averiguar cuál fue la excepción consultando el seguimiento de pila y Logcat para obtener información más detallada sobre el error. En este caso, Logcat tiene el siguiente mensaje de error:

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type [service type] did not stop within its timeout: [component name]"

Solución:

Asegúrate de que todos los servicios en primer plano de corta duración finalicen su trabajo y llamen a stopForeground(int) dentro del límite de tiempo del sistema.

Haz que tus servicios en primer plano implementen Service.onTimeout(int,int). Asegúrate de que tu implementación de ese método llame a stopSelf() de inmediato.

Excepción interna: ForegroundServiceDidNotStartInTimeException

Cuando inicias un servicio llamando a context.startForegroundService(), ese servicio tiene unos segundos para promocionarse a un servicio en primer plano llamando a ServiceCompat.startForeground(). Si el servicio no lo hace, arroja una ForegroundServiceDidNotStartInTimeException interna.

Diagnóstico:

Puedes averiguar cuál fue la excepción consultando el seguimiento de pila y Logcat para obtener información más detallada sobre el error. En este caso, Logcat tiene el siguiente mensaje de error:

android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException:
Context.startForegroundService() did not then call Service.startForeground()

Solución:

Asegúrate de que todos los servicios en primer plano recién creados llamen a ServiceCompat.startForeground() en unos segundos.

WorkManager:

También puedes ver esta excepción con los trabajadores de WorkManager que ejecutan un servicio en primer plano (llaman a setForegound o setForegroundAsync). Cuando el ciclo de vida de dos trabajadores en primer plano se superpone cuando un trabajador intenta iniciar un servicio en primer plano mientras un servicio en primer plano que se ejecutaba anteriormente intenta cerrarse, esta falla se acompañará del siguiente registro:

Re-initializing SystemForegroundService after a request to shut-down

Se introdujo una solución para esta falla en la versión 2.10.5 de WorkManager.

Si tu app encuentra esta excepción, actualiza a la versión más reciente de WorkManager y notifica cualquier problema persistente al registro de errores de WorkManager issue tracker.

ForegroundServiceStartNotAllowedException

Error:

El sistema arroja ForegroundServiceStartNotAllowedException.

Causa:

Por lo general, esto se debe a que la app inicia un servicio en primer plano desde el segundo plano cuando no hay una exención válida.

A partir de Android 12 (nivel de API 31), las apps no pueden iniciar servicios en primer plano mientras se ejecutan en segundo plano, con algunas exenciones específicas. Si intentas iniciar un servicio en primer plano desde el segundo plano y no cumples con los requisitos de una de las exenciones, el sistema arroja ForegroundServiceStartNotAllowedException. El sistema también lo hace si no cumples con los requisitos de la exención.

Por ejemplo, una app podría tener un botón en el que un usuario puede hacer clic, lo que hace que la app realice algún procesamiento y, luego, inicie un servicio en primer plano. En este caso, existe el peligro de que el usuario haga clic en el botón y, luego, coloque la app en segundo plano de inmediato. Luego, la app intentaría iniciar el servicio desde el segundo plano. Si la app no cumple con una de las exenciones especificadas, el sistema arroja una ForegroundServiceStartNotAllowedException.

Además, algunas exenciones tienen un límite de tiempo corto. Por ejemplo, hay una breve exención si tu app inicia un servicio en primer plano en respuesta a un mensaje de FCM de alta prioridad. Si no inicias el servicio con la suficiente rapidez, obtendrás una ForegroundServiceStartNotAllowedException.

A veces, las exenciones específicas se vuelven más restrictivas con las nuevas versiones de Android. Si cambiaste la versión de Android a la que se orienta tu app, consulta la documentación sobre los cambios en los servicios en primer plano y confirma que tu app aún cumple con una de las exenciones permitidas.

Solución:

Cambia el flujo de trabajo de tu app para que no necesite iniciar servicios en primer plano mientras la app está en segundo plano o confirma que tu app cumple con una de las exenciones.

Puedes usar componentes optimizados para ciclos de vida para administrar el ciclo de vida de tu app, de modo que no intentes iniciar un servicio en primer plano desde el segundo plano de forma involuntaria.

SecurityException

Error:

El sistema arrojaSecurityException.

Causa:

Tu app intentó iniciar un servicio en primer plano sin tener los permisos necesarios.

  • Si una app se orienta a Android 9 (nivel de API 28) o versiones posteriores, debe tener el permiso FOREGROUND_SERVICE para iniciar un servicio en primer plano.
  • Si una app se orienta a Android 14 (nivel de API 34) o versiones posteriores, debe cumplir con todos los requisitos previos para su tipo de servicio en primer plano. Estos requisitos previos se detallan en la documentación de los tipos de servicios en primer plano. En particular, ten en cuenta los siguientes requisitos:
    • Varios tipos de servicios en primer plano requieren permisos específicos del tiempo de ejecución. Por ejemplo, un servicio en primer plano de mensajería remota debe tener el permiso FOREGROUND_SERVICE_REMOTE_MESSAGING.
  • En varios casos, existen restricciones adicionales durante el uso en los permisos que necesitan algunos tipos de servicios en primer plano. Estos permisos solo se otorgan a la app mientras está en primer plano (con algunas excepciones específicas). Esto significa que, incluso si tu app solicitó y se le otorgó uno de estos permisos, si la app intenta iniciar el servicio en primer plano mientras está en segundo plano, el sistema arrojará una SecurityException, incluso si la app tiene una exención para iniciar un servicio en primer plano desde el segundo plano. Para obtener más información, consulta Restricciones para iniciar servicios en primer plano que necesitan permisos durante el uso.
    • Es posible que obtengas una SecurityException si solicitaste los permisos necesarios, pero inicias el servicio en primer plano antes de confirmar que se otorgaron los permisos requeridos.

Solución:

Antes de iniciar el servicio en primer plano, solicita todos los permisos de servicio en primer plano adecuados y confirma que cumpliste con todos los demás requisitos previos del tiempo de ejecución.