Pular para o conteúdo

Configurando a UI da Caixa de Entrada do Pushwoosh para Android

A UI da Caixa de Entrada do Pushwoosh oferece uma tela de caixa de entrada pronta para Android (a Caixa de Entrada do Aplicativo com o “ícone de sino”) sobre o backend da caixa de entrada do Pushwoosh. Ela renderiza mensagens em um dos cinco tipos de cartão, suporta botões de CTA em linha e está aberta para personalização de estilo através de atributos XML ou código.

Pré-requisitos

Anchor link to

Adicionar a biblioteca

Anchor link to

Adicione o plugin Kotlin e os dois módulos do Pushwoosh ao build.gradle do seu aplicativo:

build.gradle
apply plugin: 'kotlin-android'
dependencies {
implementation 'com.pushwoosh:pushwoosh-inbox:6.+'
implementation 'com.pushwoosh:pushwoosh-inbox-ui:6.+'
}

Fixe pushwoosh-inbox e pushwoosh-inbox-ui na mesma versão da sua dependência com.pushwoosh:pushwoosh existente. Substitua + pela versão atual do SDK do Pushwoosh para Android.

Se o seu aplicativo usa ProGuard para ofuscação de código, mantenha a classe do plugin da caixa de entrada:

proguard-rules.pro
-keep public class com.pushwoosh.inbox.PushwooshInboxPlugin {
*;
}

Exibir a caixa de entrada

Anchor link to

Apresente a caixa de entrada como uma tela independente ou incorpore-a como um fragmento em seu próprio layout.

Como uma atividade (activity):

startActivity(Intent(this, InboxActivity::class.java))

Como um fragmento (fragment):

supportFragmentManager.beginTransaction()
.replace(R.id.inboxContainer, PushwooshInboxUi.createInboxFragment())
.commitAllowingStateLoss()

Tipos de cartão

Anchor link to

A UI da Caixa de Entrada resolve um tipo de cartão por mensagem. O resolvedor lê displayType do objeto data do payload do push, que o SDK entrega em actionParams. Um displayType que nomeia um tipo de cartão conhecido sempre renderiza esse tipo, recorrendo a classic apenas se os campos obrigatórios do tipo estiverem ausentes. Essa resolução não depende da configuração heurística abaixo.

Quando displayType está ausente, a mensagem é renderizada como uma linha simples, a menos que você opte pela heurística de imagem/texto:

PushwooshInboxStyle.richCardsHeuristicEnabled = true

Com a heurística ativada, uma imagem sem título renderiza banner, uma imagem com título e corpo renderiza captioned, e qualquer outra coisa recorre a classic.

displayTypeAparênciaCampo obrigatório do payloadDegrada para
bannerImagem de sangria total, sem textoimagem (ícone da mensagem ou data.attachment)classic quando não há imagem
captionedImagem no topo, título + corpo abaixoimagem, title e content da mensagemclassic quando a imagem, título ou corpo estão ausentes
classicÍcone + título + corpo— (título, corpo e ícone esperados)—
carouselGaleria de múltiplas imagens deslizáveistitle e content da mensagem, data.carousel (1–5 slides)classic quando não há slides ou não há título/corpo
videoPôster com selo de reprodução, reprodutor em tela cheia ao tocardata.video (url + poster opcional)classic quando não há descritor

O cartão Apple Wallet do InboxKit para iOS não tem um equivalente para Android. Uma mensagem com displayType: "wallet" sempre é renderizada como classic no Android.

Cartão de carrossel

Anchor link to

Os slides ficam em data.carousel. Cada slide precisa de uma image. title (sobreposição de legenda) e url (aberto ao tocar) são opcionais. Um slide sem imagem é descartado, e no máximo 5 slides são exibidos.

POST https://api.pushwoosh.com/json/1.3/createMessage
{
"request": {
"application": "XXXXX-XXXXX",
"auth": "API_TOKEN",
"notifications": [{
"send_date": "now",
"content": "Swipe through this week's drops",
"inbox_days": 7,
"data": {
"displayType": "carousel",
"carousel": [
{ "image": "https://cdn.example.com/inbox/1.jpg", "title": "New in", "url": "myapp://product/1" },
{ "image": "https://cdn.example.com/inbox/2.jpg", "title": "On sale", "url": "myapp://product/2" }
]
},
"platforms": [3]
}]
}
}

Cartão de vídeo

Anchor link to

O descritor fica em data.video: url é obrigatório, poster é uma imagem de visualização opcional. Tocar no pôster abre um reprodutor em tela cheia.

POST https://api.pushwoosh.com/json/1.3/createMessage
{
"request": {
"application": "XXXXX-XXXXX",
"auth": "API_TOKEN",
"notifications": [{
"send_date": "now",
"content": "Tap to play",
"inbox_days": 7,
"data": {
"displayType": "video",
"video": {
"url": "https://cdn.example.com/inbox/clip.mp4",
"poster": "https://cdn.example.com/inbox/poster.jpg"
}
},
"platforms": [3]
}]
}
}

Ler dados personalizados de uma mensagem

Anchor link to

Para que um push apareça na caixa de entrada, a solicitação createMessage da API de Mensagens deve incluir inbox_image, inbox_date ou inbox_days. Sem um desses campos, o push é entregue como uma notificação regular e nunca chega ao feed da caixa de entrada. Dados personalizados de formato livre vão em data, que o SDK expõe como actionParams em InboxMessage:

PushwooshInboxUi.onMessageClickListener = OnInboxMessageClickListener { message ->
val params = message.actionParams?.let { JSONObject(it) }
val promoId = params?.optString("promo_id")
if (!promoId.isNullOrEmpty()) {
navigateToPromo(promoId)
}
}

Adicionar botões de CTA em linha

Anchor link to

Uma mensagem pode conter botões de chamada para ação (call-to-action) em linha dentro de data.buttons:

POST https://api.pushwoosh.com/json/1.3/createMessage
{
"request": {
"application": "XXXXX-XXXXX",
"auth": "API_TOKEN",
"notifications": [{
"send_date": "now",
"content": "Tap a button to claim or save",
"inbox_image": "https://cdn.example.com/inbox/promo.png",
"inbox_days": 7,
"data": {
"displayType": "captioned",
"promo_id": "SUMMER2026",
"buttons": [
{ "title": "Claim", "url": "https://example.com/promo/SUMMER2026" },
{ "title": "Read", "action": "markRead" },
{ "title": "Save", "action": "custom", "tag": "save_promo" }
]
},
"platforms": [3]
}]
}
}

Cada botão precisa de um title. A resolução segue esta prioridade:

  • action definido como dismiss ou markRead (sem distinção entre maiúsculas e minúsculas) executa essa ação.
  • Caso contrário, uma url não vazia e analisável resolve para uma ação openURL.
  • Caso contrário, o toque resolve para uma ação personalizada, e cada chave extra no objeto do botão é encaminhada para o seu ouvinte (listener) como seu payload.

Intercepte os toques de PushwooshInboxUi.onButtonClickListener. Retorne true para permitir que o SDK execute a ação padrão do botão, false para suprimi-la:

PushwooshInboxUi.onButtonClickListener = OnInboxButtonClickListener { message, button ->
when (val action = button.action) {
is InboxCardButton.Action.OpenUrl -> true
InboxCardButton.Action.Dismiss, InboxCardButton.Action.MarkRead -> true
is InboxCardButton.Action.Custom -> {
when (action.payload.optString("tag")) {
"save_promo" -> saveCurrentPromoLocally(message)
}
true
}
}
}

Personalizar o estilo

Anchor link to

Defina cores, fontes e estados de vazio/erro a partir do código através de PushwooshInboxStyle:

PushwooshInboxStyle.accentColor = ContextCompat.getColor(this, R.color.brand_accent)
PushwooshInboxStyle.titleColor = ContextCompat.getColor(this, R.color.brand_title)
PushwooshInboxStyle.listEmptyText = "You have no messages yet"
PushwooshInboxStyle.showToolbar = false

Ou aplique o mesmo conjunto de atributos como um tema, listado em attrs.xml: inboxAccentColor, inboxTitleColor, inboxBackgroundColor, inboxDefaultIcon e o restante dos atributos de cor e aparência. Ambas as abordagens, além de um aplicativo de exemplo completo, estão no repositório pushwoosh-inbox-ui-android-sdk InboxSample.

Selo de mensagens não lidas

Anchor link to
PushwooshInbox.unreadMessagesCount { result ->
if (result.isSuccess) {
val count = result.data
} else {
Log.e("App", "Failed to get unread count", result.exception)
}
}