Las apps orientadas a Android 12 (nivel de API 31) o versiones posteriores no pueden iniciar servicios en primer plano
mientras se ejecutan en segundo plano, excepto en algunos casos especiales. Si una app intenta iniciar un
servicio en primer plano mientras se ejecuta en segundo plano y el servicio en primer plano no cumple con uno de los casos excepcionales, el sistema arroja una
ForegroundServiceStartNotAllowedException.
Además, si una app quiere iniciar un servicio en primer plano que necesita permisos durante el uso (por ejemplo, permisos de sensor corporal, cámara, micrófono o ubicación), no puede crear el servicio mientras la app está en segundo plano, incluso si la app entra en una de las exenciones de las restricciones de inicio en segundo plano. El motivo se explica en la sección Restricciones para iniciar servicios en primer plano que necesitan permisos durante el uso.
Exenciones de las restricciones de inicio en segundo plano
En las siguientes situaciones, tu app puede iniciar servicios en primer plano incluso mientras se ejecuta en segundo plano:
- La app viene de un estado visible para el usuario, como una actividad.
- La app puede iniciar una actividad en segundo plano, excepto en los casos en que tiene una actividad en la pila de actividades de una tarea existente.
Tu app recibe un mensaje de prioridad alta mediante Firebase Cloud Messaging.
El usuario realiza una acción en un elemento de la IU relacionado con tu app. Por ejemplo, puede interactuar con un cuadro de ayuda, notificación, widget o una actividad.
Tu app invoca una alarma exacta para completar una acción que solicita el usuario.
Tu app recibe un evento relacionado con el geovallado o la transición del reconocimiento de actividad.
Después de que el dispositivo se reinicia y recibe la
ACTION_BOOT_COMPLETED,ACTION_LOCKED_BOOT_COMPLETED, oACTION_MY_PACKAGE_REPLACEDacción de intent en un receptor de transmisiones.La app recibe la
ACTION_TIMEZONE_CHANGED,ACTION_TIME_CHANGED, oACTION_LOCALE_CHANGEDacción de intent en un receptor de transmisiones.Tu app recibe el
ACTION_TRANSACTION_DETECTEDevento deNfcService.Apps que tienen permisos o funciones del sistema específicos, como propietarios del dispositivo y propietarios deperfiles.
Tu app usa el administrador de dispositivo complementario y declara el
REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUNDpermiso o elREQUEST_COMPANION_RUN_IN_BACKGROUNDpermiso. Siempre que sea posible, usaREQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND.El usuario desactiva las optimizaciones de batería para tu app.
Tu app tiene el
SYSTEM_ALERT_WINDOWpermiso. Nota: Si tu app está orientada a Android 15 o versiones posteriores, debe tener el permisoSYSTEM_ALERT_WINDOWy la app debe tener actualmente una ventana superpuesta visible.
Restricciones para iniciar servicios en primer plano que necesitan permisos durante el uso
En Android 14 (nivel de API 34) o versiones posteriores, existen situaciones especiales que debes tener en cuenta si inicias un servicio en primer plano que necesita permisos durante el uso.
Si tu app está orientada a Android 14 o versiones posteriores, el sistema operativo verifica cuando creas un servicio en primer plano para asegurarse de que tu app tenga todos los permisos adecuados para ese tipo de servicio. Por ejemplo, cuando creas un
servicio en primer plano de tipo
micrófono, el sistema
operativo verifica que tu app tenga actualmente el
RECORD_AUDIO
permiso. Si no tienes ese permiso, el sistema arroja una
SecurityException.
En el caso de los permisos durante el uso, esto causa un problema potencial. Si tu app tiene un
permiso durante el uso, solo tiene ese permiso mientras está en primer
plano. Esto significa que, si tu app está en segundo plano y trata de crear un servicio en primer plano de tipo cámara, ubicación o micrófono, el sistema ve que tu app no tiene actualmente los permisos necesarios y arroja una SecurityException.
Del mismo modo, si tu app está en segundo plano y crea un servicio de salud que necesita el permiso BODY_SENSORS, la app no tiene ese permiso actualmente y el sistema arroja una excepción.
(Esto no se aplica si es un servicio de salud que necesita permisos diferentes,
como ACTIVITY_RECOGNITION.) Llamar a
PermissionChecker.checkSelfPermission()
does not evita este problema. Si tu app tiene un permiso durante el uso y llama a checkSelfPermission() para verificar si tiene ese permiso, el método muestra PERMISSION_GRANTED incluso si la app está en segundo plano. Cuando el método muestra PERMISSION_GRANTED, dice "tu app tiene este permiso mientras está en uso".
Por este motivo, si tu servicio en primer plano necesita un permiso durante el uso, debes llamar a Context.startForegroundService() o Context.bindService() mientras tu app tenga una actividad visible, a menos que el servicio entre en una de las exenciones definidas.
Exenciones de las restricciones de permisos durante el uso
En algunas situaciones, incluso si se inicia un servicio en primer plano mientras la app se ejecuta en segundo plano, puede acceder a la información de la ubicación, la cámara y el micrófono mientras la app se ejecuta en primer plano ("durante el uso").
En estas mismas situaciones, si el servicio declara un tipo de servicio en primer plano
de location y lo inicia una app que
tiene el permiso ACCESS_BACKGROUND_LOCATION, este servicio puede acceder a la información de la ubicación en todo momento, incluso cuando
la app se ejecuta en segundo plano.
La siguiente lista contiene estas situaciones:
- Un componente del sistema inicia el servicio.
- El servicio se inicia interactuando con widgets de apps.
- El servicio se inicia mediante la interacción con una notificación.
- El servicio se inicia como un
PendingIntentque se envía desde una app diferente y visible. - El servicio se inicia con una app que es un controlador de política de dispositivo que se ejecuta en el modo de propietario del dispositivo.
- Una app que proporciona el
VoiceInteractionServiceinicia el servicio. - Una app que tiene el permiso privilegiado
START_ACTIVITIES_FROM_BACKGROUNDinicia el servicio.
Cómo determinar qué servicios se ven afectados en tu app
Cuando pruebes tu app, inicia sus servicios en primer plano. Si un servicio iniciado tiene acceso restringido a la ubicación, el micrófono y la cámara, aparecerá el siguiente mensaje en Logcat:
Foreground service started from background can not have \ location/camera/microphone access: service SERVICE_NAME