Cómo optimizar tu app para Descanso y App Standby

Android tiene dos funciones de ahorro de energía que extienden la duración de la batería para los usuarios, ya que administran el comportamiento de las apps cuando un dispositivo no está conectado a una fuente de alimentación: Descanso y App Standby. La función Doze reduce el consumo de batería, ya que posterga la actividad de red y de CPU en segundo plano para las apps cuando el dispositivo no se usa durante períodos prolongados. La suspensión de apps aplaza la actividad de red en segundo plano para las apps que no tienen actividad reciente del usuario.

Mientras el dispositivo está en modo Descanso, el acceso de las apps a ciertos recursos que consumen mucha batería se aplaza hasta el período de mantenimiento. Las restricciones específicas se enumeran en Restricciones para la administración de batería.

Doze y App Standby administran el comportamiento de todas las apps que se ejecutan en Android 6.0 o versiones posteriores, independientemente de si se orientan específicamente al nivel de API objetivo 23. Para garantizar la mejor experiencia para los usuarios, prueba tu app en los modos Descanso y App Standby, y realiza los ajustes necesarios en el código. Se proporcionan detalles en las siguientes secciones.

Comprende el modo Descanso

Si un usuario deja un dispositivo desconectado y quieto durante un período, con la pantalla apagada, el dispositivo entra en el modo Descanso. En el modo Descanso, el sistema intenta conservar la batería restringiendo el acceso de las apps a la red y a los servicios que consumen mucha CPU. También impide que las apps accedan a la red y aplaza sus trabajos, sincronizaciones y alarmas estándar.

Periódicamente, el sistema sale de Doze durante un breve período para permitir que las apps completen sus actividades diferidas. Durante este período de mantenimiento, el sistema ejecuta todas las sincronizaciones, los trabajos y las alarmas pendientes, y permite que las apps accedan a la red.

Figura 1: Doze proporciona un período de mantenimiento recurrente para que las apps usen la red y controlen las actividades pendientes.

Cuando finaliza el período de mantenimiento, el sistema vuelve a entrar en Descanso, suspende el acceso a la red y aplaza los trabajos, las sincronizaciones y las alarmas. Con el tiempo, el sistema programa períodos de mantenimiento con menos frecuencia, lo que ayuda a reducir el consumo de batería en casos de inactividad más prolongada cuando el dispositivo no se está cargando.

Cuando el usuario activa el dispositivo moviéndolo, encendiendo la pantalla o conectando un cargador, el sistema sale de Doze y todas las apps reanudan la actividad normal.

Restricciones del modo Descanso

El sistema aplica las siguientes restricciones a tus apps mientras están en modo de Descanso:

Lista de tareas para el modo de Descanso

  • Si es posible, usa Firebase Cloud Messaging (FCM) para la mensajería descendente.
  • Si tus usuarios deben ver una notificación de inmediato, usa el tipo de mensaje RemoteNotification. Para obtener más orientación, consulta la documentación de FCM sobre el tipo de mensaje RemoteNotification.
  • Proporciona información suficiente dentro de la carga útil del mensaje inicial para que no sea necesario el acceso posterior a la red.
  • Establece alarmas críticas con setAndAllowWhileIdle() y setExactAndAllowWhileIdle().
  • Prueba tu app en el modo Descanso.

Cómo adaptar tu app a Descanso

Doze puede afectar a las apps de manera diferente, según las capacidades que ofrezcan y los servicios que usen. Muchas apps funcionan con normalidad en los ciclos de Doze sin modificaciones. En algunos casos, debes optimizar la forma en que tu app administra la red, las alarmas, los trabajos y las sincronizaciones. Las apps deben poder administrar las actividades de manera eficiente durante cada período de mantenimiento.

Para ayudar con la programación de alarmas, puedes usar dos métodos de AlarmManager: setAndAllowWhileIdle() y setExactAndAllowWhileIdle(). Con estos métodos, puedes configurar alarmas que se activen incluso si el dispositivo está en modo Descanso.

También es probable que la restricción de Doze en el acceso a la red afecte a tu app, en especial si esta depende de mensajes en tiempo real, como avisos o notificaciones. Si tu app requiere una conexión persistente a la red para recibir mensajes, usa Firebase Cloud Messaging (FCM) si es posible.

Para confirmar que tu app se comporte como se espera con el modo Descanso, puedes usar comandos de adb para forzar al sistema a entrar y salir de este modo, y observar el comportamiento de tu app. Para obtener más detalles, consulta Pruebas con los modos Descanso y App Standby.

Información sobre el modo App Standby

La función de App Standby permite que el sistema determine que una app está inactiva cuando el usuario no la usa de forma activa. El sistema toma esta determinación cuando el usuario no toca la app durante un período determinado y no se aplica ninguna de las siguientes condiciones:

  • El usuario inicia de manera explícita la app.
  • La app tiene un proceso que se ejecuta en primer plano, ya sea como una actividad o un servicio en primer plano, o bien que está en uso por otra actividad o servicio en primer plano.
  • La app genera una notificación que los usuarios ven en la pantalla de bloqueo o en la bandeja de notificaciones.

Cuando el usuario conecta el dispositivo a una fuente de alimentación, el sistema libera las apps del estado en espera, lo que les permite acceder libremente a la red y ejecutar cualquier trabajo y sincronización pendientes. Si el dispositivo está inactivo durante períodos prolongados, el sistema permite que las apps inactivas accedan a la red aproximadamente una vez al día.

Usa FCM para interactuar con tu app mientras el dispositivo está inactivo

Firebase Cloud Messaging (FCM) es un servicio de nube a dispositivo que te permite admitir la mensajería descendente en tiempo real entre los servicios de backend y las apps en dispositivos Android. FCM proporciona una conexión única y persistente a la nube. Todas las apps que necesitan mensajería en tiempo real pueden compartir esta conexión. Esta conexión compartida optimiza significativamente el consumo de batería, ya que hace que no sea necesario que varias apps mantengan sus propias conexiones persistentes independientes, lo que puede agotar la batería rápidamente. Por este motivo, si tu app requiere la integración de mensajes con un servicio de backend, te recomendamos que uses FCM, si es posible, en lugar de mantener tu propia conexión de red persistente.

FCM está optimizado para funcionar con los modos de inactividad Descanso y App Standby. El tipo de mensaje RemoteNotification de FCM te permite activar tu app para atraer al usuario. En el modo Doze o de App en espera, el sistema entrega el mensaje y le otorga a la app acceso temporal a los servicios de red y bloqueos de activación parciales, y, luego, devuelve el dispositivo o la app al estado inactivo. Para las notificaciones visibles para el usuario que son urgentes, considera usar los tipos de mensajes RemoteNotification para habilitar la entrega en el modo Doze. Estos mensajes pueden generar notificaciones. Consulta la guía de FCM sobre RemoteNotification para obtener más información.

Para los mensajes que no generan notificaciones, como mantener actualizado el contenido de la app en segundo plano o iniciar sincronizaciones de datos, usa mensajes de FCM BackgroundSync. Estos mensajes son de baja prioridad de forma intencional y pueden retrasarse o limitarse para optimizar la batería del dispositivo.

Como práctica recomendada general, si tu app requiere mensajería descendente, usa FCM. Si tu app ya usa FCM, asegúrate de que use RemoteNotification para los mensajes que generan notificaciones para el usuario.

No uses RemoteNotification en las siguientes situaciones:

  • Cuando una notificación definitivamente no se mostrará.
  • Para la entrega inmediata de mensajes que solo actualizan el estado de la app, como mantener actualizado el contenido de la app en segundo plano o iniciar sincronizaciones de datos.
  • Como un medio para solicitarle al usuario final que otorgue permisos

Compatibilidad con otros casos prácticos

Casi todas las apps pueden admitir el modo Descanso si administran la conectividad de red, las alarmas, los trabajos y las sincronizaciones, y si usan mensajes de FCM. Para un conjunto limitado de casos de uso, esto podría ser insuficiente. Para esos casos, el sistema proporciona una lista configurable de apps que están parcialmente exentas de las optimizaciones de Descanso y App Standby.

Una app que está parcialmente exenta puede usar la red y mantener bloqueos de activación parciales durante los modos Descanso y App Standby. Sin embargo, se siguen aplicando otras restricciones a la app, al igual que a otras apps. Por ejemplo, los trabajos y las sincronizaciones de la app se aplazan en el nivel de API 23 y versiones anteriores, y no se activan sus alarmas AlarmManager habituales. Para verificar si actualmente se encuentra en la lista de exenciones, la app puede llamar a isIgnoringBatteryOptimizations().

Los usuarios pueden configurar manualmente la lista de apps exentas en Configuración > Batería > Optimización de batería. Como alternativa, el sistema proporciona formas para que las apps les pidan a los usuarios que las eximan:

Para verificar si se encuentra en la lista de excepciones, la app puede llamar a isIgnoringBatteryOptimizations().

Pruebas con los modos Descanso y App Standby

Para garantizar una excelente experiencia para tus usuarios, prueba tu app por completo en los modos Descanso y App Standby.

Cómo probar tu app con Descanso

Para probar el modo de Doze, haz lo siguiente:

  1. Configura un dispositivo de hardware o un dispositivo virtual con una imagen del sistema de Android 6.0 (nivel de API 23) o una versión posterior.
  2. Conecta el dispositivo a la máquina de desarrollo y luego instala tu app.
  3. Ejecuta tu app y déjala activa.
  4. Ejecuta el siguiente comando para forzar el modo de inactividad en el sistema:
        $ adb shell dumpsys deviceidle force-idle
        
  5. Cuando estés listo, ejecuta el siguiente comando para salir del modo de inactividad:
        $ adb shell dumpsys deviceidle unforce
        
  6. Ejecuta el siguiente comando para volver a activar el dispositivo:
        $ adb shell dumpsys battery reset
        
  7. Observa el comportamiento de tu app después de reactivar el dispositivo. Asegúrate de que la app se recupere correctamente cuando el dispositivo salga del modo Descanso.

Prueba tu app con el modo App Standby

Para probar el modo App Standby con tu app, haz lo siguiente:

  1. Configura un dispositivo de hardware o un dispositivo virtual con una imagen del sistema de Android 6.0 (nivel de API 23) o una versión posterior.
  2. Conecta el dispositivo a la máquina de desarrollo y luego instala tu app.
  3. Ejecuta tu app y déjala activa.
  4. Para forzar la app al modo de App en espera, ejecuta los siguientes comandos:
        $ adb shell dumpsys battery unplug
        $ adb shell am set-inactive <packageName> true
        
  5. Simula la activación de tu app con los siguientes comandos:
        $ adb shell am set-inactive <packageName> false
        $ adb shell am get-inactive <packageName>
        
  6. Observa el comportamiento de tu app después de activarla. Asegúrate de que la app se recupere correctamente del modo en espera. En particular, verifica si las notificaciones y los trabajos en segundo plano de tu app funcionan como se espera.

Casos de uso aceptables para la exención

En la siguiente tabla, se destacan varios casos de uso y se indica si es aceptable que las apps usen la acción de intent ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS en estas situaciones. En general, tu app no cumple con estas excepciones, a menos que la función de Descanso o de App Standby interrumpa la funcionalidad principal de la app o que haya un motivo técnico por el que tu app no pueda usar los mensajes de FCM RemoteNotification.

Para obtener más información, consulta Asistencia para otros casos de uso.

Tipo Caso de uso ¿Puede usar FCM? ¿Se acepta la exención? Notas
App de mensajería instantánea, chat o llamadas Requiere la entrega de mensajes en tiempo real a los usuarios mientras el dispositivo está en modo de Descanso o la app está en modo App Standby. Sí, usa FCM. Contenido inaceptable Usa mensajes de FCM con RemoteNotification para activar la app y acceder a la red.
Sí, pero no usa mensajes de FCM RemoteNotification.
App de mensajería instantánea, chat o llamadas, o bien app de VoIP empresarial No, no se puede usar FCM debido a la dependencia técnica de otro servicio de mensajería, o bien Descanso y App Standby interrumpen la funcionalidad principal de la app. Aceptable
app de Seguridad. Apps que protegen a los usuarios y a sus familias Si corresponde. Aceptable
App de automatización de tareas La función principal de la app es programar acciones automatizadas, como la mensajería instantánea, las llamadas de voz o la administración de fotos nuevas. Si corresponde. Aceptable
App complementaria de dispositivo periférico La función principal de la app es mantener una conexión persistente con el dispositivo periférico para proporcionarle acceso a Internet. Si corresponde. Aceptable
La app solo necesita conectarse a un dispositivo periférico de forma periódica para sincronizarse o solo necesita conectarse a dispositivos, como auriculares inalámbricos, conectados a través de perfiles de Bluetooth estándar. Si corresponde. No