콘텐츠로 건너뛰기

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 to

Add the Kotlin plugin and the two Pushwoosh modules to your app’s build.gradle:

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:

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

Show the inbox

Anchor link to

Present 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 to

Inbox 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 = true

With 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.

displayTypeAppearanceRequired payload fieldDegrades to
bannerFull-bleed image, no textimage (message icon or data.attachment)classic when no image
captionedImage on top, title + body belowimage, message title and contentclassic when the image, title or body is missing
classicIcon + title + body— (title, body and icon expected)
carouselSwipeable multi-image gallerymessage title and content, data.carousel (1–5 slides)classic when no slides or no title/body
videoPoster with play badge, full-screen player on tapdata.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.

Anchor link to

Slides 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.

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]
}]
}
}

Video card

Anchor link to

The descriptor lives in data.video: url is required, poster is an optional preview image. Tapping the poster opens a full-screen player.

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]
}]
}
}

Read custom data from a message

Anchor link to

To 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 to

A message can carry inline call-to-action buttons inside 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]
}]
}
}

Each button needs a title. Resolution follows this priority:

  • action set to dismiss or markRead (case-insensitive) runs that action.
  • Otherwise, a non-empty, parseable url resolves to an openURL action.
  • 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 to

Set 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 = false

Or 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 to
PushwooshInbox.unreadMessagesCount { result ->
if (result.isSuccess) {
val count = result.data
} else {
Log.e("App", "Failed to get unread count", result.exception)
}
}