Instructivos

Ya está aquí la aplicación de la calidad técnica de la batería: Cómo optimizar los casos de uso comunes de los bloqueos de activación

Lectura de 8 min
Alice Yuan
Ingeniera de Relaciones con Desarrolladores

En reconocimiento de que el agotamiento excesivo de la batería es una de las principales preocupaciones de los usuarios de Android, Google ha tomado medidas significativas para ayudar a los desarrolladores a crear apps más eficientes en términos de energía. El 1 de marzo de 2026, Google Play Store comenzó a lanzar los tratamientos de calidad técnica de los bloqueos de activación para mejorar el agotamiento de la batería. Este tratamiento se lanzará de forma gradual en las apps afectadas durante las próximas semanas. Las apps que superen constantemente el umbral de "Bloqueo de activación parcial excesivo" en Android vitals pueden tener impactos tangibles en su presencia en la tienda, incluidas advertencias en su ficha de Play Store y la exclusión de las plataformas de descubrimiento, como las recomendaciones.

appDetails.png

Es posible que los usuarios vean una advertencia en tu ficha de Play Store si tu app supera el umbral de comportamiento inadecuado. 

Esta iniciativa elevó la eficiencia de la batería a una métrica esencial junto con las métricas de estabilidad, como las fallas y las ANR. El "umbral de comportamiento inadecuado" se define como mantener un bloqueo de activación parcial no exento durante al menos dos horas en promedio mientras la pantalla está apagada en más del 5% de las sesiones de usuario en los últimos 28 días. Un bloqueo de activación está exento si es un bloqueo de activación del sistema que ofrece beneficios claros para el usuario que no se pueden optimizar más, como la reproducción de audio, el acceso a la ubicación o la transferencia de datos iniciada por el usuario. Puedes ver la definición completa de los bloqueos de activación excesivos en nuestra documentación de Android vitals.

Como parte de nuestra iniciativa en curso para mejorar la duración de la batería en todo el ecosistema de Android, analizamos miles de apps y cómo usan los bloqueos de activación parciales. Si bien los bloqueos de activación a veces son necesarios, a menudo vemos que las apps los mantienen de manera ineficiente o innecesaria cuando existen soluciones más eficientes. En esta entrada de blog, se abordarán las situaciones más comunes en las que se producen bloqueos de activación excesivos y nuestras recomendaciones para optimizarlos.Ya vimos un éxito medible de socios como WHOOP, que aprovecharon estas recomendaciones para optimizar su comportamiento en segundo plano.

Uso de un servicio en primer plano en comparación con los bloqueos de activación parciales

A menudo, vimos que los desarrolladores tienen dificultades para comprender la diferencia entre dos conceptos cuando realizan la ejecución en segundo plano: el servicio en primer plano y los bloqueos de activación parciales.

Un servicio en primer plano es una API de ciclo de vida que le indica al sistema que una app está realizando un trabajo perceptible por el usuario y no debe finalizarse para recuperar memoria, pero no impide automáticamente que la CPU entre en suspensión cuando se apaga la pantalla. Por el contrario, un bloqueo de activación parcial es un mecanismo diseñado específicamente para mantener la CPU en funcionamiento incluso cuando la pantalla está apagada. 

Si bien un servicio en primer plano suele ser necesario para continuar con una acción del usuario, una adquisición manual de un bloqueo de activación parcial solo es necesaria junto con un servicio en primer plano durante la actividad de la CPU. Además, no necesitas usar un bloqueo de activación si ya utilizas una API que mantiene el dispositivo activo. 

Consulta el diagrama de flujo en Elige la API adecuada para mantener el dispositivo activo para asegurarte de comprender bien qué herramienta usar para evitar adquirir un bloqueo de activación en situaciones en las que no es necesario.

Bibliotecas de terceros que adquieren bloqueos de activación

Es común que una app descubra que se marcó por bloqueos de activación excesivos que mantiene un SDK de terceros o una API del sistema que actúa en su nombre. Para identificar y resolver estos bloqueos de activación, te recomendamos que sigas estos pasos:

  • Verifica Android vitals: Busca el nombre exacto del bloqueo de activación ofensivo en el panel de bloqueos de activación parciales excesivos. Haz una referencia cruzada de este nombre con la guía para identificar los bloqueos de activación creados por otras APIs para ver si se creó con una API del sistema conocida o una biblioteca de Jetpack. Si es así, es posible que debas optimizar tu uso de la API y consultar la guía recomendada.
  • Captura un seguimiento del sistema: Si no se puede identificar fácilmente el bloqueo de activación, reproduce el problema de bloqueo de activación de forma local con un seguimiento del sistema y examínalo con la IU de Perfetto. Puedes obtener más información para hacerlo en la Depuración de otros tipos de bloqueos de activación excesivos sección de esta entrada de blog.
  • Evalúa alternativas: Si una biblioteca de terceros ineficiente es responsable y no se puede configurar para respetar la duración de la batería, considera comunicar el problema a los propietarios del SDK, buscar un SDK alternativo o compilar la funcionalidad de forma interna.

Situaciones comunes de bloqueo de activación

A continuación, se incluye un desglose de algunos de los casos de uso específicos que revisamos, junto con la ruta recomendada para optimizar la implementación del bloqueo de activación.

Carga o descarga iniciada por el usuario

Ejemplos de casos de uso:

  • Apps de transmisión de video en las que el usuario activa la descarga de un archivo grande para acceder sin conexión
  • Apps de copia de seguridad de contenido multimedia en las que el usuario activa la carga de sus fotos recientes a través de un mensaje de notificación

Cómo reducir los bloqueos de activación: 

  • No adquieras un bloqueo de activación manual. En su lugar, usa la API de transferencia de datos iniciada por el usuario (UIDT). Esta es la ruta designada para las tareas de transferencia de datos de larga duración iniciadas por el usuario, y está exenta de los cálculos de bloqueo de activación excesivo.

Sincronizaciones periódicas o únicas en segundo plano

Ejemplos de casos de uso:

  • Una app realiza sincronizaciones periódicas en segundo plano para obtener datos para el acceso sin conexión. 
  • Apps de podómetro que obtienen el recuento de pasos de forma periódica

Cómo reducir los bloqueos de activación:

  • No adquieras un bloqueo de activación manual. Usa WorkManager configurado para trabajos periódicos o únicos. WorkManager respeta el estado del sistema mediante la agrupación de tareas y tiene un intervalo periódico mínimo (15 minutos), que suele ser suficiente para las actualizaciones en segundo plano. 
  • Si identificas bloqueos de activación creados por WorkManager o JobScheduler con un uso elevado de bloqueos de activación, es posible que hayas configurado incorrectamente tu trabajador para que no se complete en ciertas situaciones. Considera analizar los motivos de detención del trabajador, en especial si ves muchas instancias de STOP_REASON_TIMEOUT
workManager.getWorkInfoByIdFlow(syncWorker.id)
  .collect { workInfo ->
      if (workInfo != null) {
        val stopReason = workInfo.stopReason
        logStopReason(syncWorker.id, stopReason)
      }
  }
  • Además de registrar los motivos de detención del trabajador, consulta nuestra documentación sobre cómo depurar tus trabajadores. Además, considera recopilar y analizar seguimientos del sistema para comprender cuándo se adquieren y liberan los bloqueos de activación.
  • Por último, consulta nuestro caso de éxito con WHOOP, en el que pudieron descubrir un problema con la configuración de sus trabajadores y reducir significativamente el impacto de los bloqueos de activación.

Comunicación Bluetooth

Ejemplos de casos de uso:

  • La app para dispositivos complementarios le solicita al usuario que vincule su dispositivo externo Bluetooth.
  • La app para dispositivos complementarios detecta eventos de hardware en un dispositivo externo y cambios visibles para el usuario en la notificación.
  • El usuario de la app del dispositivo complementario inicia una transferencia de archivos entre el dispositivo móvil y el Bluetooth.
  • La app para dispositivos complementarios realiza actualizaciones ocasionales de firmware en un dispositivo externo a través de Bluetooth.

Cómo reducir los bloqueos de activación:

  • Usa la vinculación de dispositivos complementarios para vincular dispositivos Bluetooth y evitar adquirir un bloqueo de activación manual durante la vinculación de Bluetooth. 
  • Consulta la guía para comunicarse en segundo plano para comprender cómo realizar la comunicación Bluetooth en segundo plano. 
  • El uso de WorkManager suele ser suficiente si no hay impacto en el usuario en una comunicación retrasada. Si se considera necesario un bloqueo de activación manual, solo mantén el bloqueo de activación durante la actividad de Bluetooth o el procesamiento de los datos de actividad.

Seguimiento y ubicación

Ejemplos de casos de uso:

  • Apps de fitness que almacenan en caché datos de ubicación para subirlos más tarde, como trazar rutas de carrera
  • Apps de entrega de comida que extraen datos de ubicación con una frecuencia alta para actualizar el progreso de la entrega en una notificación o IU de widget

Cómo reducir los bloqueos de activación:

  • Consulta nuestra guía para optimizar el uso de la ubicación. Considera implementar tiempos de espera, aprovechar la agrupación de solicitudes de ubicación o utilizar actualizaciones de ubicación pasivas para garantizar la eficiencia de la batería.
  • Cuando solicitas actualizaciones de ubicación con las APIs de FusedLocationProvider o LocationManager, el sistema activa automáticamente un dispositivo durante la devolución de llamada del evento de ubicación. Este bloqueo de activación breve y administrado por el sistema está exento de los cálculos de bloqueo de activación parcial excesivo.
  • Evita adquirir un bloqueo de activación continuo y separado para almacenar en caché los datos de ubicación, ya que es redundante. En su lugar, conserva los eventos de ubicación en la memoria o el almacenamiento local y aprovecha WorkManager para procesarlos en intervalos periódicos.
override fun onCreate(savedInstanceState: Bundle?) {
    locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult?) {
            locationResult ?: return
            // System wakes up CPU for short duration
            for (location in locationResult.locations){
                // Store data in memory to process at another time
            }
        }
    }
}

Supervisión de sensores de alta frecuencia

Ejemplos de casos de uso:

  • Apps de podómetro que recopilan pasos o distancia recorrida de forma pasiva 
  • Apps de seguridad que supervisan los sensores del dispositivo para detectar cambios rápidos en tiempo real y proporcionar funciones como la detección de fallas o la detección de caídas

Cómo reducir los bloqueos de activación:

  • Si usas SensorManager, reduce el uso a intervalos periódicos y solo cuando el usuario haya otorgado acceso de forma explícita a través de una interacción de la IU. La supervisión de sensores de alta frecuencia puede agotar la batería en gran medida debido a la cantidad de activaciones y procesamiento de la CPU que se producen.
  • Si realizas un seguimiento de los recuentos de pasos o la distancia recorrida, en lugar de usar SensorManager, aprovecha la API de Recording o considera utilizar Health Connect para acceder a los recuentos de pasos históricos y agregados del dispositivo para capturar datos de una manera eficiente en términos de batería.
  • Si registras un sensor con SensorManager, especifica un maxReportLatencyUs de 30 segundos o más para aprovechar el procesamiento por lotes de sensores y minimizar la frecuencia de las interrupciones de la CPU. Cuando el dispositivo se active posteriormente con otro activador, como una interacción del usuario, la recuperación de la ubicación o un trabajo programado, el sistema enviará de inmediato los datos del sensor almacenados en caché.
val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)

sensorManager.registerListener(this,
                 accelerometer,
                 samplingPeriodUs, // How often to sample data
                 maxReportLatencyUs // Key for sensor batching 
              )
  • Si tu app requiere datos de ubicación y de sensores, sincroniza su recuperación y procesamiento de eventos. Al aprovechar las lecturas de los sensores en el breve bloqueo de activación que mantiene el sistema para las actualizaciones de ubicación, evitas la necesidad de un bloqueo de activación para mantener la CPU activa. Usa un trabajador o un bloqueo de activación de corta duración para controlar la carga y el procesamiento de estos datos combinados.

Mensajería remota

Ejemplos de casos de uso:

  • Apps complementarias de supervisión de video o sonido que necesitan supervisar eventos que ocurren en un dispositivo externo conectado mediante una red local
  • Apps de mensajería que mantienen una conexión de socket de red con la variante de escritorio

Cómo reducir los bloqueos de activación:

  • Si los eventos de red se pueden procesar en el servidor, usa FCM para recibir información sobre el cliente. Puedes optar por programar un trabajador acelerado si se requiere un procesamiento adicional de los datos de FCM. 
  • Si los eventos se deben procesar en el cliente a través de una conexión de socket, no se necesita un bloqueo de activación para detectar interrupciones de eventos. Cuando los paquetes de datos llegan a la radio Wi-Fi o celular, el hardware de radio activa una interrupción de hardware en forma de bloqueo de activación del kernel. Luego, puedes optar por programar un trabajador o adquirir un bloqueo de activación para procesar los datos.
  • Por ejemplo, si usas ktor-network para detectar paquetes de datos en un socket de red, solo debes adquirir un bloqueo de activación cuando los paquetes se hayan entregado al cliente y deban procesarse.
val readChannel = socket.openReadChannel()
while (!readChannel.isClosedForRead) {
    // CPU can safely sleep here while waiting for the next packet
    val packet = readChannel.readRemaining(1024) 
    if (!packet.isEmpty) {
         // Data Arrived: The system woke the CPU and we should keep it awake via manual wake lock (urgent) or scheduling a worker (non-urgent)
         performWorkWithWakeLock { 
              val data = packet.readBytes()
              // Additional logic to process data packets
         }
    }
}

Resumen

Si adoptan estas soluciones recomendadas para casos de uso comunes, como las sincronizaciones en segundo plano, el seguimiento de la ubicación, la supervisión de sensores y la comunicación de red, los desarrolladores pueden trabajar para reducir el uso innecesario de bloqueos de activación. Para seguir aprendiendo, lee nuestra otra entrada de blog técnica o mira nuestro video técnico sobre cómo descubrir y depurar bloqueos de activación: Optimiza la batería de tu app con la métrica de bloqueo de activación de Android vitals. Además, consulta nuestra documentación actualizada sobre bloqueos de activación. Para ayudarnos a seguir mejorando nuestros recursos técnicos, comparte cualquier comentario adicional sobre nuestra guía en nuestra encuesta de comentarios sobre la documentación.

Escrito por:

Seguir leyendo