Live Updates en Android
Pushwoosh es compatible con las Live Updates de Android a través del módulo pushwoosh-liveupdates (SDK 6.9.0 y posteriores). Una Live Update es una notificación continua, de estilo de progreso, que el sistema promociona en la pantalla de bloqueo, en el cajón de notificaciones y como un chip de estado en la barra de estado, para que los usuarios puedan seguir una actividad sin abrir tu aplicación.
Todo el ciclo de vida se gestiona desde el servidor: tu backend envía un push cuando la actividad comienza, más pushes a medida que avanza y un push final cuando termina. El SDK renderiza cada uno automáticamente.
¿Qué son las Live Updates?
Anchor link toLas Live Updates se introdujeron en Android 16 (API 36) como una forma de mostrar una actividad iniciada por el usuario y sensible al tiempo de principio a fin. Se basan en las notificaciones centradas en el progreso de la plataforma y en la API Notification.ProgressStyle. Conceptualmente, son la contraparte en Android de las Live Activities de iOS.
Esta página cubre únicamente la integración con Pushwoosh. Para conocer el comportamiento de la plataforma, las reglas de promoción y las guías de diseño, consulta la documentación oficial de Android:
- Notificaciones centradas en el progreso
- Crear notificaciones de actualización en vivo (Views)
- Crear notificaciones de actualización en vivo (Compose)
¿Cuándo usar las Live Updates?
Anchor link toLas Live Updates están pensadas para una actividad que está en curso, iniciada por el usuario y es sensible al tiempo; algo con un inicio y un final claros que al usuario le importa activamente en este momento. Escenarios típicos para los clientes de Pushwoosh:
- Entrega de comida — pedido aceptado, en preparación, en camino, llegando.
- Servicios de transporte y taxi — conductor asignado, en ruta, llegando, viaje en curso.
- Seguimiento de pedidos y envíos — estado en vivo de un pedido que está activamente en tránsito.
- Deportes y medios en vivo — marcador y tiempo del partido a medida que se desarrolla el juego.
- Fitness — un entrenamiento o carrera activa con tiempo transcurrido y progreso.
- Fintech — un flujo de transacción o verificación que avanza por sus etapas.
Debido a que el ciclo de vida es impulsado por eventos reales que tu backend ya conoce (un pedido cambia de estado, un mensajero se mueve), una Live Update suele ser una llamada a la API conectada a tu flujo de eventos existente, no algo que una persona envía manualmente.
Requisitos
Anchor link to- Android 16 (API 36) o superior. En dispositivos más antiguos, el módulo permanece inactivo y cada llamada a la API de Live Update es una operación segura que no hace nada (no-op).
- Pushwoosh Android SDK 6.9.0 o posterior.
Añadir el módulo pushwoosh-liveupdates
Anchor link toAñade la dependencia a tu app/build.gradle:
dependencies { implementation 'com.pushwoosh:pushwoosh-liveupdates:<latest-version>'}Reemplaza <latest-version> con la versión actual de Maven Central.
El módulo se descubre automáticamente al iniciar. Declara el permiso requerido POST_PROMOTED_NOTIFICATIONS, registra su propio canal de notificaciones e intercepta los pushes de Live Update antes de la ruta de notificación predeterminada. No hay código de inicialización adicional: el SDK establece los indicadores de ongoing y promoted, descarga el icono grande, mapea los botones de acción y publica la notificación por ti.
Enviar una Live Update
Anchor link toEnvías Live Updates a través de la API de Mensajería v2 añadiendo un objeto live_update al bloque de contenido android. Utiliza una solicitud transactional: una Live Update se dirige al usuario específico cuya actividad está rastreando. El campo schedule es obligatorio; { "after": "0s" } envía inmediatamente. El ciclo de vida tiene tres operaciones, establecidas en live_update.op:
OPERATION_START— primer push para una actividad. Publica la notificación en curso.OPERATION_UPDATE— un push posterior para la misma actividad. La actualiza en el mismo lugar, de forma silenciosa.OPERATION_END— push terminal. Descarta la notificación.
Todos los pushes que pertenecen a la misma actividad deben compartir el mismo live_update.id. Ese id une las actualizaciones y también es lo que usas para descartar la actualización desde la aplicación.
Cada push describe completamente la notificación; nada se hereda del push anterior. Vuelve a enviar cada campo que quieras conservar, como los segmentos y el icono grande, con cada OPERATION_UPDATE; un campo omitido se renderiza como ausente.
Parámetros de Live Update
Anchor link toEstas claves van dentro del objeto live_update del bloque de contenido android. El título, el cuerpo y el icono grande utilizan los campos de push estándar de Android (title, body, custom_icon), enviados junto con live_update.
| Parámetro | Tipo | Descripción |
|---|---|---|
op | string | Operación del ciclo de vida: OPERATION_START, OPERATION_UPDATE o OPERATION_END. Obligatorio. |
id | string | ID de actividad estable compartido por todos los pushes de una Live Update. Obligatorio. |
progress | int | Valor de progreso, medido contra la suma de las longitudes de los segmentos. |
progress_indeterminate | bool | Muestra una animación indeterminada en lugar de un valor concreto. |
progress_bar | bool | Muestra la barra de progreso. El valor predeterminado es true. |
segments | array | Segmentos de progreso ordenados, cada uno { "color": "#RRGGBB", "length": N }. |
extras | object | Datos arbitrarios pasados a un proveedor de estilo personalizado. |
when | int64 | Ancla de tiempo del encabezado, en milisegundos de la época (epoch). |
chronometer | bool | Muestra el tiempo del encabezado como un cronómetro en funcionamiento. |
chronometer_count_down | bool | Un cronómetro en funcionamiento cuenta hacia atrás en lugar de hacia adelante. |
show_when | bool | Muestra la columna de tiempo del encabezado. El valor predeterminado es true. |
Los cuatro campos de tiempo se combinan de la siguiente manera: con show_when establecido en false, el tiempo se oculta; de lo contrario, when es el ancla, chronometer lo convierte en un contador en vivo, y chronometer_count_down hace que ese contador vaya hacia atrás.
Push de inicio
Anchor link tocurl -X POST https://api.pushwoosh.com/messaging/v2/notify \ -H "Authorization: Token YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "transactional": { "application": "XXXXX-XXXXX", "platforms": ["ANDROID"], "users": { "list": ["customer-42"] }, "payload": { "content": { "localized_content": { "default": { "android": { "title": "Order #4521", "body": "We are preparing your order", "custom_icon": "https://example.com/restaurant.png", "live_update": { "op": "OPERATION_START", "id": "order_4521", "progress": 1, "segments": [ { "color": "#34A853", "length": 3 }, { "color": "#FBBC05", "length": 4 }, { "color": "#4285F4", "length": 3 } ], "extras": { "eta": "18:40" } } } } } } }, "schedule": { "after": "0s" }, "message_type": "MESSAGE_TYPE_TRANSACTIONAL" } }'Push de actualización
Anchor link toEnvía un OPERATION_UPDATE con el mismo id cada vez que la actividad avance. Repite los segmentos y el icono; una actualización que los omita se renderizará sin ellos.
curl -X POST https://api.pushwoosh.com/messaging/v2/notify \ -H "Authorization: Token YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "transactional": { "application": "XXXXX-XXXXX", "platforms": ["ANDROID"], "users": { "list": ["customer-42"] }, "payload": { "content": { "localized_content": { "default": { "android": { "title": "Order #4521", "body": "Your courier is on the way", "custom_icon": "https://example.com/restaurant.png", "live_update": { "op": "OPERATION_UPDATE", "id": "order_4521", "progress": 7, "segments": [ { "color": "#34A853", "length": 3 }, { "color": "#FBBC05", "length": 4 }, { "color": "#4285F4", "length": 3 } ] } } } } } }, "schedule": { "after": "0s" }, "message_type": "MESSAGE_TYPE_TRANSACTIONAL" } }'Push de finalización
Anchor link toEl push terminal solo necesita la operación y el id.
curl -X POST https://api.pushwoosh.com/messaging/v2/notify \ -H "Authorization: Token YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "transactional": { "application": "XXXXX-XXXXX", "platforms": ["ANDROID"], "users": { "list": ["customer-42"] }, "payload": { "content": { "localized_content": { "default": { "android": { "live_update": { "op": "OPERATION_END", "id": "order_4521" } } } } } }, "schedule": { "after": "0s" }, "message_type": "MESSAGE_TYPE_TRANSACTIONAL" } }'Personalizar la apariencia
Anchor link toEl SDK incluye un estilo de progreso predeterminado construido a partir de progress, progress_indeterminate y segments. Para tener control total sobre la barra de progreso, implementa LiveUpdateProgressStyleProvider y da forma a un Notification.ProgressStyle tú mismo.
El proveedor es el único punto de personalización. El SDK sigue siendo responsable de la configuración del canal, los indicadores de ongoing y promoted, el icono grande, los botones de acción y el tiempo del encabezado; un proveedor personalizado solo puede dar forma a la barra de progreso, por lo que no puede romper la elegibilidad para la promoción. Debe ser sin estado (stateless): deriva el estilo devuelto únicamente del LiveUpdateState proporcionado. Si lanza una excepción, el SDK recurre al estilo predeterminado y la notificación se publica de todos modos.
import android.app.Notification;import androidx.annotation.NonNull;import com.pushwoosh.liveupdates.LiveUpdateProgressStyleProvider;import com.pushwoosh.liveupdates.LiveUpdateSegment;import com.pushwoosh.liveupdates.LiveUpdateState;import java.util.List;
public class OrderStyleProvider implements LiveUpdateProgressStyleProvider { @NonNull @Override public Notification.ProgressStyle createStyle(@NonNull LiveUpdateState state) { Notification.ProgressStyle style = new Notification.ProgressStyle(); if (state.getProgress() != null) { style.setProgress(state.getProgress()); } style.setProgressIndeterminate(state.isProgressIndeterminate());
List<LiveUpdateSegment> segments = state.getSegments(); int boundary = 0; for (int i = 0; i < segments.size(); i++) { LiveUpdateSegment seg = segments.get(i); style.addProgressSegment( new Notification.ProgressStyle.Segment(seg.getLength()).setColor(seg.getColor())); boundary += seg.getLength(); if (i < segments.size() - 1) { style.addProgressPoint(new Notification.ProgressStyle.Point(boundary)); } } return style; }}import android.app.Notificationimport com.pushwoosh.liveupdates.LiveUpdateProgressStyleProviderimport com.pushwoosh.liveupdates.LiveUpdateState
class OrderStyleProvider : LiveUpdateProgressStyleProvider { override fun createStyle(state: LiveUpdateState): Notification.ProgressStyle { val style = Notification.ProgressStyle() state.progress?.let { style.setProgress(it) } style.setProgressIndeterminate(state.isProgressIndeterminate)
val segments = state.segments var boundary = 0 segments.forEachIndexed { i, seg -> style.addProgressSegment( Notification.ProgressStyle.Segment(seg.length).setColor(seg.color)) boundary += seg.length if (i < segments.size - 1) { style.addProgressPoint(Notification.ProgressStyle.Point(boundary)) } } return style }}Registra el proveedor con una etiqueta <meta-data> en AndroidManifest.xml. La clase debe tener un constructor público sin argumentos.
<meta-data android:name="com.pushwoosh.LIVE_UPDATE_STYLE_PROVIDER" android:value="com.example.OrderStyleProvider" />Usa LiveUpdateState.getExtras() para leer el JSON que enviaste en live_update.extras y adaptar el estilo a tus propios datos de negocio.
Gestionar Live Updates desde tu aplicación
Anchor link toEl servidor impulsa cada OPERATION_START, OPERATION_UPDATE y OPERATION_END, por lo que no hay una API del lado de la aplicación para publicar o actualizar una Live Update. La fachada PushwooshLiveUpdates cubre solo lo que el servidor no puede hacer: descartar una actualización localmente y verificar cuáles están en pantalla.
import com.pushwoosh.liveupdates.PushwooshLiveUpdates;
// Descarta una Live Update específica cuando el usuario finaliza la actividad en la aplicación,// sin esperar el push terminal "end" del servidorPushwooshLiveUpdates.endLiveUpdate("order_4521");
// Lista los IDs de actividad que esta aplicación muestra actualmenteList<String> active = PushwooshLiveUpdates.getActiveIds();
// Borra todo lo que esta aplicación está mostrando, por ejemplo, al cerrar sesiónPushwooshLiveUpdates.endAllLiveUpdates();Todos los métodos son seguros para llamar desde cualquier hilo y son una operación que no hace nada (no-op) en dispositivos por debajo de Android 16.