Android 10 (nivel de API 29) y las versiones posteriores restringen cuándo las apps pueden iniciar actividades cuando se ejecutan en segundo plano. Estas restricciones ayudan a minimizar las interrupciones para el usuario y a darle más control de lo que aparece en la pantalla.
En esta guía, se presentan las notificaciones como una alternativa para iniciar actividades en segundo plano. También se enumeran los casos específicos en los que no se aplica la restricción.
Cómo mostrar notificaciones
En casi todos los casos, las apps en segundo plano deben mostrar notificaciones urgentes para proporcionar información urgente al usuario en lugar de iniciar una actividad directamente. Estas notificaciones incluyen el manejo de una llamada telefónica entrante o un reloj despertador activo.
Este sistema de alertas y recordatorios basados en notificaciones presenta distintas ventajas para los usuarios:
- Cuando usa el dispositivo, el usuario ve una notificación de atención que le permite responder. El usuario conserva el contexto actual y controla el contenido que ve en la pantalla.
- Las notificaciones urgentes respetan las reglas de No interrumpir del usuario. Por ejemplo, cuando está activado el modo No interrumpir, los usuarios pueden aceptar llamadas provenientes de determinados contactos o emisores recurrentes.
- Cuando la pantalla del dispositivo está apagada, el intent en pantalla completa se inicia inmediatamente.
- En la pantalla de Configuración del dispositivo, el usuario puede ver qué apps han enviado notificaciones recientemente, incluso desde canales específicos. En esa pantalla, el usuario puede controlar sus preferencias de notificaciones.
Cuándo las apps pueden iniciar actividades
Las apps que se ejecutan en Android 10 o versiones posteriores pueden iniciar actividades cuando se cumple al menos una de las siguientes condiciones:
- La app tiene una ventana visible, como una actividad en primer plano.
- La app tiene una actividad en la pila de actividades de la tarea en primer plano.
La app tiene una actividad en la pila de actividades de una tarea existente en la pantalla Recientes.
La app tiene una actividad que se inició muy recientemente.
La app llamó a
finish()
en una actividad muy recientemente. Esta condición se aplica solo cuando la app tenía una actividad en primer plano o una actividad en la pila de actividades de la tarea en primer plano en el momento en que se llamó afinish()
.La app tiene uno de los siguientes servicios que está vinculado por el sistema. Es posible que estos servicios deban iniciar una IU.
AccessibilityService
AutofillService
CallRedirectionService
HostApduService
InCallService
TileService
(no aplicable en Android 14 [nivel de API 34] y versiones posteriores)VoiceInteractionService
VrListenerService
.
La app tiene un servicio que está vinculado por una app diferente y visible. La app vinculada al servicio debe permanecer visible para que la app en segundo plano inicie las actividades correctamente.
La app recibe una notificación
PendingIntent
del sistema. En el caso de intents pendientes para servicios y receptores de emisión, la app puede iniciar actividades durante unos segundos después de que se envía el intent pendiente.La app recibe un
PendingIntent
que se envía desde una app diferente y visible.La app recibe una transmisión del sistema en la que se espera que inicie una IU. Los ejemplos incluyen
ACTION_NEW_OUTGOING_CALL
ySECRET_CODE_ACTION
. La app puede iniciar actividades durante unos segundos luego del envío de la transmisión.La app se asocia con un dispositivo de hardware complementario a través de la API de
CompanionDeviceManager
. Esta API permite que la app inicie actividades en respuesta a acciones que realiza el usuario en un dispositivo vinculado.La app es un controlador de política de dispositivo que se ejecuta en el modo de propietario del dispositivo. Algunos ejemplos de casos prácticos son dispositivos empresariales completamente administrados y dispositivos dedicados, como los de señalización digital y de kiosco.
El usuario otorgó el permiso
SYSTEM_ALERT_WINDOW
a la app.
Se requiere la habilitación cuando se inician actividades desde PendingIntents
Para evitar inicios de actividades accidentales según las condiciones enumeradas, a partir de Android 14, existen APIs explícitas que te permiten habilitar o inhabilitar el otorgamiento de permisos a una app para iniciar actividades.
Las apps que se segmenten para Android 15 o versiones posteriores ya no otorgarán privilegios de inicio de actividad en segundo plano (BAL) de forma implícita a los objetos PendingIntents
que creen. Se requiere la aceptación explícita. Para ello, estas son las opciones según si la app envía o crea PendingIntents
.
Por el remitente del PendingIntent
Las apps segmentadas para Android 14 o versiones posteriores que deseen iniciar un PendingIntent
deben cumplir con los siguientes requisitos:
- Cumplir con las condiciones indicadas y
- Habilita el inicio de actividades en segundo plano según esas excepciones.
Esta habilitación solo debe ocurrir si el desarrollador de la app sabe que esta va a iniciar una Activity.
Para hacerlo, la app debe pasar un paquete ActivityOptions
con setPendingIntentBackgroundActivityStartMode(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
a PendingIntent.send()
o métodos similares.
Por el creador del PendingIntent
Las apps que se segmentan para Android 15 o versiones posteriores y crean un PendingIntent
ahora deben habilitar explícitamente el inicio de actividades en segundo plano si desean que esos PendingIntents
se puedan iniciar en las condiciones enumeradas.
En la mayoría de los casos, la app que inicia el PendingIntent
debería ser la que habilite la opción.
Sin embargo, si la app que crea el archivo necesita otorgar estos privilegios, haz lo siguiente:
- El
PendingIntent
se puede iniciar en cualquier momento en que la app de creación esté visible. - El
PendingIntent
se puede iniciar en cualquier momento si la app de creación tiene privilegios especiales.
Para hacerlo, la app debe pasar un paquete ActivityOptions
con setPendingIntentCreatorBackgroundActivityStartMode
(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
a PendingIntent.getActivity()
o métodos similares.
Lee la documentación de referencia pertinente para obtener más detalles:
ActivityOptions.setPendingIntentBackgroundActivityStartMode
ActivityOptions.setPendingIntentCreatorBackgroundActivityStartMode
Modo estricto
A partir de Android 16, el desarrollador de la app puede habilitar el modo estricto para recibir notificaciones cuando se bloquea el inicio de una actividad (o cuando existe el riesgo de que se bloquee cuando se aumente el SDK objetivo de la app).
Código de ejemplo para habilitar desde el principio en el método Application.onCreate()
de tu Application, Activity o algún otro componente de la aplicación:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectBlockedBackgroundActivityLaunch()
.penaltyLog()
.build());
)
}
Para obtener más detalles, consulta la documentación del modo estricto.