Configuración de la interfaz de usuario de la bandeja de entrada de Pushwoosh para Android
La interfaz de usuario de la bandeja de entrada de Pushwoosh ofrece una pantalla de bandeja de entrada de Android ya preparada (la “Bandeja de entrada de la aplicación” con el icono de la campana) sobre el backend de la bandeja de entrada de Pushwoosh. Renderiza los mensajes en uno de los cinco tipos de tarjetas, admite botones de CTA en línea y está abierta a la personalización de estilo a través de atributos XML o código.
Requisitos previos
Anchor link to- El SDK base de Pushwoosh para Android ya está integrado y enviando notificaciones push.
- Soporte de Kotlin en el módulo de tu aplicación (
apply plugin: 'kotlin-android').
Añadir la librería
Anchor link toAñade el plugin de Kotlin y los dos módulos de Pushwoosh al build.gradle de tu aplicación:
apply plugin: 'kotlin-android'
dependencies { implementation 'com.pushwoosh:pushwoosh-inbox:6.+' implementation 'com.pushwoosh:pushwoosh-inbox-ui:6.+'}Fija pushwoosh-inbox y pushwoosh-inbox-ui a la misma versión que tu dependencia existente de com.pushwoosh:pushwoosh. Reemplaza + con la versión actual del SDK de Pushwoosh para Android.
Si tu aplicación utiliza ProGuard para la ofuscación de código, mantén la clase del plugin de la bandeja de entrada:
-keep public class com.pushwoosh.inbox.PushwooshInboxPlugin { *;}Mostrar la bandeja de entrada
Anchor link toPresenta la bandeja de entrada como una pantalla independiente, o incrústala como un fragmento dentro de tu propio diseño.
Como una actividad:
startActivity(Intent(this, InboxActivity::class.java))Como un fragmento:
supportFragmentManager.beginTransaction() .replace(R.id.inboxContainer, PushwooshInboxUi.createInboxFragment()) .commitAllowingStateLoss()Tipos de tarjetas
Anchor link toLa interfaz de usuario de la bandeja de entrada resuelve un tipo de tarjeta por mensaje. El resolutor lee displayType del objeto data del payload de la notificación push, que el SDK entrega bajo actionParams. Un displayType que nombra un tipo de tarjeta conocido siempre renderiza ese tipo, recurriendo a classic solo si faltan los campos requeridos del tipo. Esta resolución no depende de la configuración heurística a continuación.
Cuando displayType está ausente, el mensaje se renderiza como una fila simple a menos que optes por la heurística de imagen/texto:
PushwooshInboxStyle.richCardsHeuristicEnabled = trueCon la heurística activada, una imagen sin título renderiza banner, una imagen con título y cuerpo renderiza captioned, y cualquier otra cosa recurre a classic.
displayType | Apariencia | Campo de payload requerido | Se degrada a |
|---|---|---|---|
banner | Imagen a sangre completa, sin texto | image (icono del mensaje o data.attachment) | classic cuando no hay imagen |
captioned | Imagen en la parte superior, título + cuerpo debajo | image, title y content del mensaje | classic cuando falta la imagen, el título o el cuerpo |
classic | Icono + título + cuerpo | — (se esperan título, cuerpo e icono) | — |
carousel | Galería de múltiples imágenes deslizable | title y content del mensaje, data.carousel (1–5 diapositivas) | classic cuando no hay diapositivas o no hay título/cuerpo |
video | Póster con insignia de reproducción, reproductor a pantalla completa al tocar | data.video (url + poster opcional) | classic cuando no hay descriptor |
La tarjeta de Apple Wallet de InboxKit de iOS no tiene un equivalente en Android. Un mensaje con displayType: "wallet" siempre se renderiza como classic en Android.
Tarjeta de carrusel
Anchor link toLas diapositivas se encuentran en data.carousel. Cada diapositiva necesita una image. title (superposición de leyenda) y url (se abre al tocar) son opcionales. Una diapositiva sin imagen se descarta, y se muestran como máximo 5 diapositivas.
{ "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] }] }}Tarjeta de video
Anchor link toEl descriptor se encuentra en data.video: url es obligatorio, poster es una imagen de vista previa opcional. Al tocar el póster se abre un reproductor a pantalla completa.
{ "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] }] }}Leer datos personalizados de un mensaje
Anchor link toPara que una notificación push aparezca en la bandeja de entrada, la solicitud createMessage de la API de Mensajes debe incluir inbox_image, inbox_date o inbox_days. Sin uno de esos campos, la notificación push se entrega como una notificación regular y nunca llega al feed de la bandeja de entrada. Los datos personalizados de formato libre van en data, que el SDK expone como actionParams en InboxMessage:
PushwooshInboxUi.onMessageClickListener = OnInboxMessageClickListener { message -> val params = message.actionParams?.let { JSONObject(it) } val promoId = params?.optString("promo_id") if (!promoId.isNullOrEmpty()) { navigateToPromo(promoId) }}Añadir botones de CTA en línea
Anchor link toUn mensaje puede llevar botones de llamada a la acción (CTA) en línea dentro de data.buttons:
{ "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ón necesita un title. La resolución sigue esta prioridad:
actionestablecido endismissomarkRead(sin distinción de mayúsculas y minúsculas) ejecuta esa acción.- De lo contrario, una
urlno vacía y analizable se resuelve en una acciónopenURL. - De lo contrario, el toque se resuelve en una acción personalizada, y cada clave extra en el objeto del botón se reenvía a tu listener como su payload.
Intercepta los toques desde PushwooshInboxUi.onButtonClickListener. Devuelve true para permitir que el SDK realice la acción predeterminada del botón, false para suprimirla:
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 el estilo
Anchor link toEstablece colores, fuentes y estados de vacío/error desde el código a través de PushwooshInboxStyle:
PushwooshInboxStyle.accentColor = ContextCompat.getColor(this, R.color.brand_accent)PushwooshInboxStyle.titleColor = ContextCompat.getColor(this, R.color.brand_title)PushwooshInboxStyle.listEmptyText = "Aún no tienes mensajes"PushwooshInboxStyle.showToolbar = falseO aplica el mismo conjunto de atributos como un tema, listado en attrs.xml: inboxAccentColor, inboxTitleColor, inboxBackgroundColor, inboxDefaultIcon, y el resto de los atributos de color y apariencia. Ambos enfoques, además de una aplicación de muestra completa, se encuentran en el repositorio pushwoosh-inbox-ui-android-sdk InboxSample.
Insignia de mensajes no leídos
Anchor link toPushwooshInbox.unreadMessagesCount { result -> if (result.isSuccess) { val count = result.data } else { Log.e("App", "Failed to get unread count", result.exception) }}