Restricciones sobre el inicio de actividades en segundo plano

Android 10 (nivel de API 29) y versiones posteriores aplican restricciones respecto de cuándo las apps pueden iniciar actividades cuando se ejecutan en segundo plano. Estas restricciones ayudan a minimizar las interrupciones que sufre el usuario y permiten que este tenga más control sobre lo que ve en la pantalla.

En esta guía, se presenta el uso de notificaciones como alternativa para el inicio de actividades en segundo plano. También se enumeran los casos específicos en los que la restricción no se aplica.

Cómo mostrar notificaciones

En casi todos los casos, las apps en segundo plano deben mostrar notificaciones sujetas a limitaciones temporales para proporcionar información urgente al usuario en lugar de iniciar una actividad. Estas notificaciones incluyen el manejo de llamadas telefónicas entrantes o una alarma de reloj activa.

Este sistema de alertas y recordatorios basado en notificaciones ofrece varias ventajas para los usuarios:

  • Cuando usa el dispositivo, el usuario recibe una notificación emergente que le permite responder. El usuario conserva el contexto actual y controla el contenido que ve en la pantalla.
  • Las notificaciones sujetas a limitaciones temporales respetan las reglas de No interrumpir del usuario. Por ejemplo, los usuarios pueden aceptar las llamadas de contactos específicos o personas que llaman recurrentemente cuando el modo No interrumpir está activado.
  • Cuando la pantalla del dispositivo está apagada, se inicia de inmediato el intent de pantalla completa.
  • En la pantalla de Configuración del dispositivo, el usuario puede ver qué apps enviaron 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 una o más 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ó hace muy poco tiempo.

  • La app llamó a finish() en una actividad muy recientemente. Esto 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ó a finish().

  • La app tiene uno de los siguientes servicios que está vinculado por el sistema. Es posible que estos servicios deban iniciar una IU.

  • La app tiene un servicio vinculado por otra app 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 los intents pendientes de servicios y receptores de emisiones, la app puede iniciar actividades durante algunos segundos después del envío del intent pendiente.

  • La app recibe un PendingIntent que se envía desde otra app visible.

  • La app recibe una transmisión del sistema en la que se espera que la app inicie una IU. Los ejemplos incluyen ACTION_NEW_OUTGOING_CALL y SECRET_CODE_ACTION. La app puede iniciar actividades durante unos segundos luego del envío de la transmisión.

  • La app está asociada 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 el usuario realiza en un dispositivo sincronizado.

  • La app es un controlador de política de dispositivo que se ejecuta en el modo de propietario del dispositivo. Algunos ejemplos de casos de uso son dispositivos empresariales completamente administrados y dispositivos dedicados, como los de señalización digital y de kiosco.

  • El usuario le otorga a la app el permiso SYSTEM_ALERT_WINDOW.

Se requiere la habilitación cuando se inician actividades desde PendingIntents

Para evitar permitir inicios de actividades accidentales según las condiciones enumeradas, a partir de Android 14, hay APIs explícitas que te permiten habilitar o inhabilitar el otorgamiento de permisos a una app para el inicio de actividades.

De forma predeterminada, las apps orientadas a Android 15 o versiones posteriores ya no otorgarán privilegios de inicio de actividad en segundo plano (BAL) de forma implícita a los PendingIntents que creen. Se requiere la habilitación explícita. Para ello, estas son las opciones según si la app envía o crea PendingIntents.

Tabla de intents pendientes
Figura 1: Flujo de decisión para los inicios de actividades en segundo plano.

Por el remitente del PendingIntent

Las apps orientadas a Android 14 o versiones posteriores que quieran iniciar un PendingIntent deben cumplir con los siguientes requisitos:

  • cumplir con las condiciones indicadas y
  • habilitar 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 la app iniciará una actividad.

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 orientadas a Android 15 o versiones posteriores que crean un PendingIntent ahora deben habilitar de forma explícita 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 debe ser la que acepte la opción. Sin embargo, si la app que crea necesita otorgar estos privilegios, haz lo siguiente:

  • El PendingIntent se puede iniciar en cualquier momento en que la app de creación esté visible.
  • Se puede iniciar PendingIntent 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) al método PendingIntent.getActivity() o a métodos similares.

Lee la documentación de referencia relevante para obtener más detalles: