跳到内容

Android 实时更新

Pushwoosh 通过 pushwoosh-liveupdates 模块(SDK 6.9.0 及更高版本)支持 Android 实时更新。实时更新是一种持续进行的、进度条样式的通知,系统会将其提升到锁屏、通知抽屉中,并在状态栏中显示为状态图标,这样用户无需打开您的应用即可跟踪活动。

整个生命周期由服务器驱动:您的后端在活动开始时发送一个推送,随着活动进展发送更多推送,并在活动结束时发送最后一个推送。SDK 会自动渲染每一个推送。

什么是实时更新

Anchor link to

实时更新是 Android 16 (API 36) 中引入的一项功能,用于从头到尾展示用户发起的、具有时效性的活动。它们建立在平台的以进度为中心的通知和 Notification.ProgressStyle API 之上。从概念上讲,它们是 Android 平台上与 iOS 实时活动相对应的功能。

本页面仅涵盖 Pushwoosh 集成。有关平台行为、提升规则和设计指南,请参阅官方 Android 文档:

何时使用实时更新

Anchor link to

实时更新适用于正在进行的、用户发起的、具有时效性的活动——即用户当前积极关心的、有明确开始和结束的事件。Pushwoosh 客户的典型场景包括:

  • 食品配送 — 订单已接受、正在准备、派送中、即将送达。
  • 网约车和出租车 — 已分配司机、司机在途中、即将到达、行程进行中。
  • 订单和货运跟踪 — 正在运输中的订单的实时状态。
  • 体育赛事和媒体直播 — 比赛进行中的比分和时间。
  • 健身 — 正在进行的锻炼或跑步,显示已用时间和进度。
  • 金融科技 — 正在经历各个阶段的交易或验证流程。

由于生命周期是由您的后端已经知道的真实事件(例如订单状态改变、快递员移动)驱动的,因此实时更新通常是在您现有事件流中连接的一个 API 调用,而不是由人工手动发送。

  • Android 16 (API 36) 或更高版本。在较旧的设备上,该模块保持非活动状态,每个实时更新 API 调用都是安全的无操作。
  • Pushwoosh Android SDK 6.9.0 或更高版本。

添加 pushwoosh-liveupdates 模块

Anchor link to

将依赖项添加到您的 app/build.gradle 文件中:

dependencies {
implementation 'com.pushwoosh:pushwoosh-liveupdates:<latest-version>'
}

请将 <latest-version> 替换为 Maven Central 上的当前版本。

该模块在启动时会自动被发现。它声明了所需的 POST_PROMOTED_NOTIFICATIONS 权限,注册了自己的通知渠道,并在默认通知路径之前拦截实时更新推送。无需额外的初始化代码——SDK 会为您设置 ongoing 和 promoted 标志、下载大图标、映射操作按钮并发布通知。

发送实时更新

Anchor link to

您可以通过 Messaging API v2 发送实时更新,方法是在 android 内容块中添加一个 live_update 对象。请使用 transactional 请求——实时更新针对的是其活动被跟踪的特定用户。schedule 字段是必需的;{ "after": "0s" } 表示立即发送。生命周期有三个操作,在 live_update.op 中设置:

  • OPERATION_START — 活动的第一个推送。发布持续进行的通知。
  • OPERATION_UPDATE — 同一活动的后续推送。在原地静默刷新它。
  • OPERATION_END — 最终推送。关闭通知。

属于同一活动的所有推送必须共享相同的 live_update.id。该 ID 将更新联系在一起,也是您从应用中关闭更新时使用的 ID。

每个推送都完整地描述了通知——没有任何内容会从上一个推送继承。对于每次 OPERATION_UPDATE,请重新发送您希望保留的每个字段,例如分段和大图标;省略的字段将被渲染为不存在。

实时更新参数

Anchor link to

这些键位于 android 内容块的 live_update 对象内部。标题、正文和大图标使用标准的 Android 推送字段(titlebodycustom_icon),与 live_update 一同发送。

参数类型描述
opstring生命周期操作:OPERATION_STARTOPERATION_UPDATEOPERATION_END。必需。
idstring同一个实时更新的所有推送共享的稳定活动 ID。必需。
progressint进度值,相对于所有分段长度的总和来衡量。
progress_indeterminatebool显示不确定动画而不是具体值。
progress_barbool是否显示进度条。默认为 true
segmentsarray有序的进度分段,每个分段为 { "color": "#RRGGBB", "length": N }
extrasobject传递给自定义样式提供程序的任意数据。
whenint64头部时间锚点,以纪元毫秒为单位。
chronometerbool将头部时间显示为运行中的计时器。
chronometer_count_downbool运行中的计时器倒计时而不是正计时。
show_whenbool是否显示头部时间列。默认为 true

四个时间字段的组合如下:当 show_when 设置为 false 时,时间被隐藏;否则 when 是锚点,chronometer 将其变为实时计数器,而 chronometer_count_down 使该计数器倒计时。

开始推送

Anchor link to
Terminal window
curl -X POST https://api.pushwoosh.com/messaging/v2/notify \
-H "Authorization: Token YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"transactional": {
"application": "XXXXX-XXXXX",
"platforms": ["ANDROID"],
"users": { "list": ["customer-42"] },
"payload": {
"content": {
"localized_content": {
"default": {
"android": {
"title": "Order #4521",
"body": "We are preparing your order",
"custom_icon": "https://example.com/restaurant.png",
"live_update": {
"op": "OPERATION_START",
"id": "order_4521",
"progress": 1,
"segments": [
{ "color": "#34A853", "length": 3 },
{ "color": "#FBBC05", "length": 4 },
{ "color": "#4285F4", "length": 3 }
],
"extras": { "eta": "18:40" }
}
}
}
}
}
},
"schedule": { "after": "0s" },
"message_type": "MESSAGE_TYPE_TRANSACTIONAL"
}
}'

更新推送

Anchor link to

每当活动向前推进时,发送一个带有相同 idOPERATION_UPDATE。重复分段和图标——省略它们的更新将渲染为没有它们。

Terminal window
curl -X POST https://api.pushwoosh.com/messaging/v2/notify \
-H "Authorization: Token YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"transactional": {
"application": "XXXXX-XXXXX",
"platforms": ["ANDROID"],
"users": { "list": ["customer-42"] },
"payload": {
"content": {
"localized_content": {
"default": {
"android": {
"title": "Order #4521",
"body": "Your courier is on the way",
"custom_icon": "https://example.com/restaurant.png",
"live_update": {
"op": "OPERATION_UPDATE",
"id": "order_4521",
"progress": 7,
"segments": [
{ "color": "#34A853", "length": 3 },
{ "color": "#FBBC05", "length": 4 },
{ "color": "#4285F4", "length": 3 }
]
}
}
}
}
}
},
"schedule": { "after": "0s" },
"message_type": "MESSAGE_TYPE_TRANSACTIONAL"
}
}'

结束推送

Anchor link to

最终的推送只需要操作和 ID。

Terminal window
curl -X POST https://api.pushwoosh.com/messaging/v2/notify \
-H "Authorization: Token YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"transactional": {
"application": "XXXXX-XXXXX",
"platforms": ["ANDROID"],
"users": { "list": ["customer-42"] },
"payload": {
"content": {
"localized_content": {
"default": {
"android": {
"live_update": {
"op": "OPERATION_END",
"id": "order_4521"
}
}
}
}
}
},
"schedule": { "after": "0s" },
"message_type": "MESSAGE_TYPE_TRANSACTIONAL"
}
}'

自定义外观

Anchor link to

SDK 提供了一个默认的进度条样式,该样式由 progressprogress_indeterminatesegments 构建。要完全控制进度条,请实现 LiveUpdateProgressStyleProvider 并自行构建一个 Notification.ProgressStyle

该提供程序是唯一的自定义点。SDK 仍然负责渠道设置、ongoing 和 promoted 标志、大图标、操作按钮和头部时间——自定义提供程序只能塑造进度条,因此不会破坏提升资格。它必须是无状态的:仅从提供的 LiveUpdateState 派生返回的样式。如果它抛出异常,SDK 会回退到默认样式,通知仍然会发布。

import android.app.Notification;
import androidx.annotation.NonNull;
import com.pushwoosh.liveupdates.LiveUpdateProgressStyleProvider;
import com.pushwoosh.liveupdates.LiveUpdateSegment;
import com.pushwoosh.liveupdates.LiveUpdateState;
import java.util.List;
public class OrderStyleProvider implements LiveUpdateProgressStyleProvider {
@NonNull
@Override
public Notification.ProgressStyle createStyle(@NonNull LiveUpdateState state) {
Notification.ProgressStyle style = new Notification.ProgressStyle();
if (state.getProgress() != null) {
style.setProgress(state.getProgress());
}
style.setProgressIndeterminate(state.isProgressIndeterminate());
List<LiveUpdateSegment> segments = state.getSegments();
int boundary = 0;
for (int i = 0; i < segments.size(); i++) {
LiveUpdateSegment seg = segments.get(i);
style.addProgressSegment(
new Notification.ProgressStyle.Segment(seg.getLength()).setColor(seg.getColor()));
boundary += seg.getLength();
if (i < segments.size() - 1) {
style.addProgressPoint(new Notification.ProgressStyle.Point(boundary));
}
}
return style;
}
}

AndroidManifest.xml 中使用 <meta-data> 标签注册提供程序。该类必须有一个公共的无参数构造函数。

<meta-data
android:name="com.pushwoosh.LIVE_UPDATE_STYLE_PROVIDER"
android:value="com.example.OrderStyleProvider" />

使用 LiveUpdateState.getExtras() 来读取您在 live_update.extras 中发送的 JSON,并根据您自己的业务数据调整样式。

从您的应用管理实时更新

Anchor link to

服务器驱动每个 OPERATION_STARTOPERATION_UPDATEOPERATION_END,因此没有应用端的 API 来发布或刷新实时更新。PushwooshLiveUpdates 接口仅涵盖服务器无法完成的操作——在本地关闭更新和检查哪些更新正在屏幕上显示。

import com.pushwoosh.liveupdates.PushwooshLiveUpdates;
// 当用户在应用内完成活动时,关闭特定的实时更新,
// 无需等待服务器的最终“结束”推送
PushwooshLiveUpdates.endLiveUpdate("order_4521");
// 列出当前由此应用显示的活动 ID
List<String> active = PushwooshLiveUpdates.getActiveIds();
// 清除此应用正在显示的所有内容,例如在注销时
PushwooshLiveUpdates.endAllLiveUpdates();

所有方法都可以安全地从任何线程调用,并且在 Android 16 以下的设备上是无操作。

相关链接

Anchor link to