跳到内容

设置 Pushwoosh Android Inbox UI

Pushwoosh Inbox UI 在 Pushwoosh 收件箱后端之上提供了一个现成的 Android 收件箱屏幕(“铃铛图标”应用内收件箱)。它以五种卡片类型之一呈现消息,支持内联 CTA 按钮,并可通过 XML 属性或代码进行样式自定义。

先决条件

Anchor link to
  • 基础 Pushwoosh Android SDK 已集成并能发送推送。
  • 您的应用模块支持 Kotlin (apply plugin: 'kotlin-android')。

将 Kotlin 插件和两个 Pushwoosh 模块添加到您应用的 build.gradle 中:

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

将 pushwoosh-inbox 和 pushwoosh-inbox-ui 固定到与您现有的 com.pushwoosh:pushwoosh 依赖项相同的版本。将 + 替换为 Pushwoosh Android SDK 的当前版本。

如果您的应用使用 ProGuard 进行代码压缩,请保留收件箱插件类:

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

显示收件箱

Anchor link to

将收件箱呈现为独立屏幕,或将其作为片段嵌入到您自己的布局中。

作为 activity:

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

作为 fragment:

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

卡片类型

Anchor link to

Inbox UI 会为每条消息解析一种卡片类型。解析器从推送有效负载的 data 对象中读取 displayType,SDK 会在 actionParams 下传递该对象。如果 displayType 命名了一个已知的卡片类型,则始终呈现该类型,仅当该类型所需的字段缺失时才回退到 classic。此解析不依赖于下面的启发式设置。

当 displayType 缺失时,消息将呈现为普通行,除非您选择启用图像/文本启发式设置:

PushwooshInboxStyle.richCardsHeuristicEnabled = true

启用启发式设置后,没有标题的图像将呈现为 banner,有标题和正文的图像将呈现为 captioned,其他任何情况都将回退到 classic。

displayType外观必需的有效负载字段降级为
banner全出血图像,无文本image (message icon or data.attachment)classic(无图像时)
captioned顶部图像,下方标题+正文image, message title and contentclassic(图像、标题或正文缺失时)
classic图标 + 标题 + 正文—(应有标题、正文和图标)—
carousel可滑动的多图库message title and content, data.carousel (1–5 slides)classic(无幻灯片或无标题/正文时)
video带播放徽章的海报,点击后全屏播放data.video (url + optional poster)classic(无描述符时)

来自 iOS InboxKit 的 Apple Wallet 卡片在 Android 上没有对应项。在 Android 上,displayType 为 "wallet" 的消息始终呈现为 classic。

轮播卡片

Anchor link to

幻灯片位于 data.carousel 中。每张幻灯片都需要一个 image。title(标题覆盖层)和 url(点击时打开)是可选的。没有图像的幻灯片将被丢弃,最多显示 5 张幻灯片。

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

视频卡片

Anchor link to

描述符位于 data.video 中:url 是必需的,poster 是可选的预览图像。点击海报会打开一个全屏播放器。

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

从消息中读取自定义数据

Anchor link to

要使推送出现在收件箱中,Messages API 的 createMessage 请求必须包含 inbox_image、inbox_date 或 inbox_days。如果没有这些字段之一,推送将作为常规通知传递,永远不会到达收件箱信息流。自由格式的自定义数据位于 data 下,SDK 在 InboxMessage 上将其公开为 actionParams:

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

添加内联 CTA 按钮

Anchor link to

消息可以在 data.buttons 内携带内联的号召性用语 (call-to-action) 按钮:

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

每个按钮都需要一个 title。解析遵循以下优先级:

  • action 设置为 dismiss 或 markRead(不区分大小写)会运行该操作。
  • 否则,一个非空且可解析的 url 会解析为一个 openURL 操作。
  • 否则,点击会解析为一个自定义操作,并且按钮对象上的每个额外键都会作为其有效负载转发到您的监听器。

从 PushwooshInboxUi.onButtonClickListener 拦截点击。返回 true 让 SDK 执行按钮的默认操作,返回 false 则禁止它:

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

自定义样式

Anchor link to

通过 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

或者,将同一组属性作为主题应用,这些属性列在 attrs.xml 中:inboxAccentColor、inboxTitleColor、inboxBackgroundColor、inboxDefaultIcon 以及其余的颜色和外观属性。这两种方法,以及一个完整的示例应用,都可以在 pushwoosh-inbox-ui-android-sdk InboxSample 仓库中找到。

未读消息徽章

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