Atualizações ao Vivo no Android
A Pushwoosh suporta as Atualizações ao Vivo do Android através do módulo pushwoosh-liveupdates (SDK 6.9.0 e posterior). Uma Atualização ao Vivo é uma notificação contínua, estilo progresso, que o sistema promove na tela de bloqueio, na gaveta de notificações e como um chip de status na barra de status, para que os usuários possam acompanhar uma atividade sem abrir seu aplicativo.
Todo o ciclo de vida é controlado pelo servidor: seu backend envia um push quando a atividade começa, mais pushes à medida que progride e um push final quando termina. O SDK renderiza cada um automaticamente.
O que são Atualizações ao Vivo
Anchor link toAs Atualizações ao Vivo foram introduzidas no Android 16 (API 36) como uma forma de destacar uma atividade iniciada pelo usuário e sensível ao tempo, do início ao fim. Elas se baseiam nas notificações centradas em progresso da plataforma e na API Notification.ProgressStyle. Conceitualmente, são a contraparte Android das Live Activities do iOS.
Esta página cobre apenas a integração com a Pushwoosh. Para o comportamento da plataforma, regras de promoção e orientações de design, consulte a documentação oficial do Android:
- Notificações centradas em progresso
- Criar notificações de atualização ao vivo (Views)
- Criar notificações de atualização ao vivo (Compose)
Quando usar as Atualizações ao Vivo
Anchor link toAs Atualizações ao Vivo são destinadas a uma atividade que está em andamento, foi iniciada pelo usuário e é sensível ao tempo — algo com um início e fim claros com os quais o usuário se importa ativamente no momento. Cenários típicos para clientes da Pushwoosh:
- Entrega de comida — pedido aceito, em preparação, saiu para entrega, chegando.
- Transporte por aplicativo e táxi — motorista atribuído, a caminho, chegando, viagem em andamento.
- Rastreamento de pedidos e remessas — status ao vivo de um pedido que está ativamente em trânsito.
- Esportes e mídia ao vivo — placar e tempo da partida conforme o jogo se desenrola.
- Fitness — um treino ou corrida ativa com tempo decorrido e progresso.
- Fintech — um fluxo de transação ou verificação passando por suas etapas.
Como o ciclo de vida é impulsionado por eventos reais que seu backend já conhece (um pedido muda de status, um entregador se move), uma Atualização ao Vivo geralmente é uma chamada de API conectada ao seu fluxo de eventos existente — não algo que uma pessoa envia manualmente.
Requisitos
Anchor link to- Android 16 (API 36) ou mais recente. Em dispositivos mais antigos, o módulo permanece inativo e cada chamada de API de Atualização ao Vivo é uma operação nula segura.
- SDK Android da Pushwoosh 6.9.0 ou posterior.
Adicionar o módulo pushwoosh-liveupdates
Anchor link toAdicione a dependência ao seu app/build.gradle:
dependencies { implementation 'com.pushwoosh:pushwoosh-liveupdates:<latest-version>'}Substitua <latest-version> pela versão atual do Maven Central.
O módulo é descoberto automaticamente na inicialização. Ele declara a permissão POST_PROMOTED_NOTIFICATIONS necessária, registra seu próprio canal de notificação e intercepta os pushes de Atualização ao Vivo antes do caminho de notificação padrão. Não há código de inicialização extra — o SDK define os sinalizadores de andamento e promovido, baixa o ícone grande, mapeia os botões de ação e posta a notificação para você.
Enviar uma Atualização ao Vivo
Anchor link toVocê envia Atualizações ao Vivo através da API de Mensagens v2 adicionando campos de Atualização ao Vivo ao objeto root_params do bloco de conteúdo android. Use uma solicitação transactional — uma Atualização ao Vivo visa o usuário específico cuja atividade ela rastreia. O campo schedule é obrigatório; { "after": "0s" } envia imediatamente. O ciclo de vida tem três operações, definidas em pw_live_op:
start— primeiro push para uma atividade. Posta a notificação em andamento.update— um push posterior para a mesma atividade. Atualiza-a no local, silenciosamente.end— push terminal. Dispensa a notificação.
Todos os pushes que pertencem à mesma atividade devem compartilhar o mesmo pw_live_id. Esse id une as atualizações e também é o que você usa para dispensar a atualização do aplicativo.
Cada push descreve completamente a notificação — nada é herdado do push anterior. Reenvie todos os campos que deseja manter, como os segmentos e o ícone grande, a cada update; um campo omitido é renderizado como ausente.
Parâmetros da Atualização ao Vivo
Anchor link toEssas chaves vão dentro do objeto root_params do bloco de conteúdo android. Título, corpo e ícone grande usam os campos de push padrão do Android (title, body, custom_icon).
| Parâmetro | Tipo | Descrição |
|---|---|---|
pw_live_op | string | Operação do ciclo de vida: start, update ou end. Obrigatório. |
pw_live_id | string | ID de atividade estável compartilhado por todos os pushes de uma Atualização ao Vivo. Obrigatório. |
pw_live_progress | int | Valor do progresso, medido em relação à soma dos comprimentos dos segmentos. |
pw_live_progress_indeterminate | bool | Mostrar uma animação indeterminada em vez de um valor concreto. |
pw_live_segments | JSON string | Segmentos de progresso ordenados, cada um {"color": "#RRGGBB", "length": N}. |
pw_live_extras | JSON string | Dados arbitrários passados para um provedor de estilo personalizado. |
pw_live_when | long | Âncora de tempo do cabeçalho, em milissegundos epoch. |
pw_live_chronometer | bool | Mostrar o tempo do cabeçalho como um cronômetro em execução. |
pw_live_chronometer_count_down | bool | Um cronômetro em execução faz contagem regressiva em vez de progressiva. |
pw_live_show_when | bool | Mostrar a coluna de tempo do cabeçalho. O padrão é true. |
Os quatro campos de tempo combinam da seguinte forma: com pw_live_show_when definido como false, o tempo é ocultado; caso contrário, pw_live_when é a âncora, pw_live_chronometer o transforma em um contador ao vivo, e pw_live_chronometer_count_down faz esse contador correr para trás.
Push de início
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", "root_params": { "pw_live_op": "start", "pw_live_id": "order_4521", "pw_live_progress": "1", "pw_live_segments": "[{\"color\":\"#34A853\",\"length\":3},{\"color\":\"#FBBC05\",\"length\":4},{\"color\":\"#4285F4\",\"length\":3}]", "pw_live_extras": "{\"eta\":\"18:40\"}" } } } } } }, "schedule": { "after": "0s" }, "message_type": "MESSAGE_TYPE_TRANSACTIONAL" } }'Push de atualização
Anchor link toEnvie um update com o mesmo pw_live_id sempre que a atividade avançar. Repita os segmentos e o ícone — uma atualização que os omite é renderizada sem eles.
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", "root_params": { "pw_live_op": "update", "pw_live_id": "order_4521", "pw_live_progress": "7", "pw_live_segments": "[{\"color\":\"#34A853\",\"length\":3},{\"color\":\"#FBBC05\",\"length\":4},{\"color\":\"#4285F4\",\"length\":3}]" } } } } } }, "schedule": { "after": "0s" }, "message_type": "MESSAGE_TYPE_TRANSACTIONAL" } }'Push de término
Anchor link toO push terminal só precisa da operação e do 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": { "root_params": { "pw_live_op": "end", "pw_live_id": "order_4521" } } } } } }, "schedule": { "after": "0s" }, "message_type": "MESSAGE_TYPE_TRANSACTIONAL" } }'Personalizar a aparência
Anchor link toO SDK vem com um estilo de progresso padrão construído a partir de pw_live_progress, pw_live_progress_indeterminate e pw_live_segments. Para ter controle total da barra de progresso, implemente LiveUpdateProgressStyleProvider e modele um Notification.ProgressStyle você mesmo.
O provedor é o único ponto de personalização. O SDK ainda é responsável pela configuração do canal, os sinalizadores de andamento e promovido, o ícone grande, os botões de ação e o tempo do cabeçalho — um provedor personalizado só pode modelar a barra de progresso, então não pode quebrar a elegibilidade para promoção. Ele deve ser sem estado: derive o estilo retornado apenas do LiveUpdateState fornecido. Se ele lançar uma exceção, o SDK recorre ao estilo padrão e a notificação ainda é postada.
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 }}Registre o provedor com uma tag <meta-data> no AndroidManifest.xml. A classe deve ter um construtor público sem argumentos.
<meta-data android:name="com.pushwoosh.LIVE_UPDATE_STYLE_PROVIDER" android:value="com.example.OrderStyleProvider" />Use LiveUpdateState.getExtras() para ler o JSON que você enviou em pw_live_extras e adaptar o estilo aos seus próprios dados de negócio.
Gerenciar Atualizações ao Vivo a partir do seu aplicativo
Anchor link toO servidor controla cada start, update e end, então não há uma API no lado do aplicativo para postar ou atualizar uma Atualização ao Vivo. A fachada PushwooshLiveUpdates cobre apenas o que o servidor não pode fazer — dispensar uma atualização localmente e verificar quais estão na tela.
import com.pushwoosh.liveupdates.PushwooshLiveUpdates;
// Dispensa uma Atualização ao Vivo específica quando o usuário conclui a atividade no aplicativo,// sem esperar pelo push terminal "end" do servidorPushwooshLiveUpdates.endLiveUpdate("order_4521");
// Lista os IDs de atividade atualmente exibidos por este aplicativoList<String> active = PushwooshLiveUpdates.getActiveIds();
// Limpa tudo que este aplicativo está mostrando, por exemplo, ao fazer logoutPushwooshLiveUpdates.endAllLiveUpdates();Todos os métodos são seguros para serem chamados de qualquer thread e são uma operação nula em dispositivos abaixo do Android 16.