Setting up Pushwoosh Inbox UI Android
이 콘텐츠는 아직 귀하의 언어로 제공되지 않습니다.
Pushwoosh Inbox UI ships a ready-made Android inbox screen (the “bell icon” App Inbox) on top of the Pushwoosh inbox backend. It renders messages in one of five card types, supports inline CTA buttons, and is open for style customization through XML attributes or code.
Prerequisites
Anchor link to- The base Pushwoosh Android SDK already integrated and sending pushes.
- Kotlin support in your app module (
apply plugin: 'kotlin-android').
Add the library
Anchor link toAdd the Kotlin plugin and the two Pushwoosh modules to your app’s build.gradle:
apply plugin: 'kotlin-android'
dependencies { implementation 'com.pushwoosh:pushwoosh-inbox:6.+' implementation 'com.pushwoosh:pushwoosh-inbox-ui:6.+'}Pin pushwoosh-inbox and pushwoosh-inbox-ui to the same version as your existing com.pushwoosh:pushwoosh dependency. Replace + with the current version of Pushwoosh Android SDK.
If your app uses ProGuard for code shrinking, keep the inbox plugin class:
-keep public class com.pushwoosh.inbox.PushwooshInboxPlugin { *;}Show the inbox
Anchor link toPresent the inbox as a standalone screen, or embed it as a fragment inside your own layout.
As an activity:
startActivity(Intent(this, InboxActivity::class.java))As a fragment:
supportFragmentManager.beginTransaction() .replace(R.id.inboxContainer, PushwooshInboxUi.createInboxFragment()) .commitAllowingStateLoss()Card types
Anchor link toInbox UI resolves a card type per message. The resolver reads displayType from the data object of the push payload, which the SDK delivers under actionParams. A displayType that names a known card type always renders that type, falling back to classic only if the type’s required fields are missing. This resolution does not depend on the heuristic setting below.
When displayType is absent, the message renders as a plain row unless you opt in to the image/text heuristic:
PushwooshInboxStyle.richCardsHeuristicEnabled = trueWith the heuristic on, an image with no title renders banner, an image with title and body renders captioned, and anything else falls back to classic.
displayType | Appearance | Required payload field | Degrades to |
|---|---|---|---|
banner | Full-bleed image, no text | image (message icon or data.attachment) | classic when no image |
captioned | Image on top, title + body below | image, message title and content | classic when the image, title or body is missing |
classic | Icon + title + body | — (title, body and icon expected) | — |
carousel | Swipeable multi-image gallery | message title and content, data.carousel (1–5 slides) | classic when no slides or no title/body |
video | Poster with play badge, full-screen player on tap | data.video (url + optional poster) | classic when no descriptor |
The Apple Wallet card from the iOS InboxKit has no Android counterpart. A message with displayType: "wallet" always renders as classic on Android.
Carousel card
Anchor link toSlides live in data.carousel. Each slide needs an image. title (caption overlay) and url (opened on tap) are optional. A slide without an image is dropped, and at most 5 slides are shown.
{ "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] }] }}Video card
Anchor link toThe descriptor lives in data.video: url is required, poster is an optional preview image. Tapping the poster opens a full-screen player.
{ "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] }] }}Read custom data from a message
Anchor link toTo make a push appear in the inbox, the Messages API createMessage request must include inbox_image, inbox_date, or inbox_days. Without one of those fields, the push is delivered as a regular notification and never reaches the inbox feed. Free-form custom data goes under data, which the SDK exposes as actionParams on InboxMessage:
PushwooshInboxUi.onMessageClickListener = OnInboxMessageClickListener { message -> val params = message.actionParams?.let { JSONObject(it) } val promoId = params?.optString("promo_id") if (!promoId.isNullOrEmpty()) { navigateToPromo(promoId) }}Add inline CTA buttons
Anchor link toA message can carry inline call-to-action buttons inside 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] }] }}Each button needs a title. Resolution follows this priority:
actionset todismissormarkRead(case-insensitive) runs that action.- Otherwise, a non-empty, parseable
urlresolves to anopenURLaction. - Otherwise, the tap resolves to a custom action, and every extra key on the button object is forwarded to your listener as its payload.
Intercept taps from PushwooshInboxUi.onButtonClickListener. Return true to let the SDK perform the button’s default action, false to suppress it:
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 } }}Customize the style
Anchor link toSet colors, fonts, and empty/error states from code through 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 = falseOr apply the same set of attributes as a theme, listed in attrs.xml: inboxAccentColor, inboxTitleColor, inboxBackgroundColor, inboxDefaultIcon, and the rest of the color and appearance attributes. Both approaches, plus a full sample app, are in the pushwoosh-inbox-ui-android-sdk InboxSample repo.
Unread messages badge
Anchor link toPushwooshInbox.unreadMessagesCount { result -> if (result.isSuccess) { val count = result.data } else { Log.e("App", "Failed to get unread count", result.exception) }}