Wear OS 设备通常用于长时间运行的体验,例如跟踪锻炼情况。这带来了一个用户体验挑战:如果用户开始一项任务,然后导航到表盘,他们该如何返回?使用启动器返回应用可能很困难,尤其是在移动时,这会造成不必要的摩擦。
解决方案是将持续性通知与 OngoingActivity 配对。
这样,设备就可以在整个界面中显示有关长时间运行的活动的信息,从而实现表盘底部可点按的图标等功能。这让用户了解后台任务,并提供了一种一键返回应用的方式。
持续性活动还可以让您的应用在更长时间内保持可见,防止系统在一段时间不活动后返回到表盘。如需了解详情,请参阅让应用始终显示在 Wear 上。
例如,在下面这款锻炼应用中,信息可在用户的表盘上显示为可点按的跑步图标:
图 1. 活动指示器。
持续性通知还会在全局应用启动器的最近用过 部分显示信息。这为用户提供了一个更便捷的位置,让他们可以查看任务的状态并重新与应用互动:
图 2. 全局启动器。
下列情况很适合使用与持续性活动相关联的持续性通知:
图 3. 计时器 :主动倒计时,并在计时器暂停或停止时结束。
图 4. 精细导航 :播报前往目的地的路线。当用户到达目的地或停止导航时结束。
图 5. 媒体 :在整个会话期间播放音乐。在用户暂停会话后立即结束。
Wear 会自动为媒体应用创建持续性活动。
请参阅“持续性活动”Codelab,通过详尽的示例了解如何为其他类型的应用创建 持续性活动。
设置
如需开始在您的应用中使用 Ongoing Activity API,请将以下依赖项添加到应用的 build.gradle 文件中:
dependencies {
implementation "androidx.wear:wear-ongoing:1.1.0"
implementation "androidx.core:core:1.18.0"
}
创建持续性活动
该过程涉及三个步骤:
- 创建一个标准
NotificationCompat.Builder并将其配置为 持续性。 - 创建并配置
OngoingActivity对象,并将 通知构建器传递给该对象。 - 将持续性活动应用于通知构建器,并发布生成的通知。
创建和配置通知
首先,创建一个 NotificationCompat.Builder 。关键步骤是调用
setOngoing(true) 将其标记为持续性通知。您还可以在此阶段设置其他通知属性,例如小图标和类别。
// Create a PendingIntent to pass to the notification builder val pendingIntent = PendingIntent.getActivity( this, 0, Intent(this, AlwaysOnActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_SINGLE_TOP }, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, ) val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("Always On Service") .setContentText("Service is running in background") .setSmallIcon(R.drawable.animated_walk) // Category helps the system prioritize the ongoing activity .setCategory(NotificationCompat.CATEGORY_WORKOUT) .setContentIntent(pendingIntent) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setOngoing(true) // Important!
创建 OngoingActivity
接下来,使用其构建器创建 OngoingActivity 的实例。OngoingActivity.Builder 需要 Context、通知 ID 和您在上一步中创建的 NotificationCompat.Builder。
配置将显示在新界面 surface 上的关键属性:
- 动画图标和静态图标:提供在活动模式和氛围模式下显示在表盘上的图标。
- 触摸 intent:当用户点按持续性活动图标时,将用户带回应用的
PendingIntent。您可以重复使用在上一步中创建的pendingIndent。
val ongoingActivity = OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder) // Sets the icon that appears on the watch face in active mode. .setAnimatedIcon(R.drawable.animated_walk) // Sets the icon that appears on the watch face in ambient mode. .setStaticIcon(R.drawable.ic_walk) // Sets the tap target to bring the user back to the app. .setTouchIntent(pendingIntent) .build()
应用于通知并发布
最后一步是将 OngoingActivity 与通知相关联,然后发布该通知。The ongoingActivity.apply() 方法会修改原始
通知构建器,添加必要的数据,以便系统可以在
额外的 surface 上显示该通知。应用后,您可以照常构建和发布通知。
// This call modifies notificationBuilder to include the ongoing activity data. ongoingActivity.apply(applicationContext) // Post the notification. startForeground(NOTIFICATION_ID, notificationBuilder.build())
向启动器添加动态状态文本
上述代码会将可点按的图标添加到表盘。如需在启动器的最近用过 部分提供更丰富、实时的更新,请创建一个Status 对象并将其附加到您的 OngoingActivity。如果您未
提供自定义 Status,系统默认使用通知的
内容文本(使用 setContentText() 设置)。如需显示动态文本,请使用
Status.Builder。您可以定义带有占位符的模板字符串,并提供 Status.Part 对象来填充这些占位符。Status.Part 可以是动态的,例如秒表或计时器。
以下示例展示了如何创建显示“Run for [a stopwatch timer]”的状态:
// Define a template with placeholders for the activity type and the timer. val statusTemplate = "#type# for #time#" // Set the start time for a stopwatch. // Use SystemClock.elapsedRealtime() for time-based parts. val runStartTime = SystemClock.elapsedRealtime() val ongoingActivityStatus = Status.Builder() // Sets the template string. .addTemplate(statusTemplate) // Fills the #type# placeholder with a static text part. .addPart("type", Status.TextPart("Run")) // Fills the #time# placeholder with a stopwatch part. .addPart("time", Status.StopwatchPart(runStartTime)) .build()
最后,通过对 OngoingActivity.Builder 调用 setStatus()
,将此 Status 链接到您的 OngoingActivity。
val ongoingActivity = OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder) // ... // Add the status to the OngoingActivity. .setStatus(ongoingActivityStatus) .build()
其他自定义
除了 Status 之外,您还可以通过以下方式自定义持续性活动或通知。不过,这些自定义可能无法使用,具体取决于 OEM 的实现。
持续性通知
- 设置的类别 决定了持续性活动的优先级。
CATEGORY_CALL:语音通话或视频通话请求,或者类似的同步通信请求CATEGORY_NAVIGATION:地图或精细导航CATEGORY_TRANSPORT:用于播放的媒体传输控件CATEGORY_ALARM:闹钟或计时器CATEGORY_WORKOUT:锻炼CATEGORY_LOCATION_SHARING:临时位置信息分享类别CATEGORY_STOPWATCH:秒表
持续性活动
动画图标:黑白矢量图标,最好为透明背景。在活动模式下会显示在表盘上。如果未提供动画图标,系统会使用默认通知图标。每个应用的默认通知图标各不相同。
静态图标 :具有透明背景的矢量图标。在氛围模式下会显示在表盘上。如果未设置动画图标,系统会在活动模式期间在表盘上使用静态图标。如果未提供该图标,系统会使用通知图标。如果二者都未设置,系统会抛出异常。应用启动器仍会使用应用图标。
OngoingActivityStatus :纯文本或
Chronometer。会显示在应用启动器的最近用过 部分。如果未提供该内容,系统会使用通知的 “上下文文本”。触摸 intent :用于在用户点按持续性活动图标时切换回应用的
PendingIntent。会显示在表盘上或启动器项上。它可以与用于启动应用的原始 intent 不同。如果未提供该 intent,系统会使用通知的内容 intent。如果二者都未设置,系统会抛出异常。LocusId: 该 ID 用于指定持续性 活动对应的启动器快捷方式。在活动持续期间,会显示在启动器的最近用过 部分。如果未提供该 ID,启动器会隐藏最近用过 部分中来自相应软件包的所有应用项,只显示持续性活动。持续性活动 ID :当应用有多个 持续性活动时,该 ID 用于消除
fromExistingOngoingActivity()调用方面的歧义。
更新持续性活动
当您需要更改状态时,应更新现有通知的持续性活动,而不是创建新的通知和持续性活动。如需更新持续性活动和已发布的通知,请使用您之前创建的对象并调用 update(),如以下示例所示:
ongoingActivity.update(context, newStatus)
在无法存储对持续性活动的引用的情况下,有一种静态方法可以恢复持续性活动。不过,我们不太推荐使用此方法:
OngoingActivity.recoverOngoingActivity(context) ?.update(context, newStatus)
停止持续性活动
当应用作为持续性活动完成运行时,只需取消持续性通知即可。
您还可以选择在应用进入前台时取消通知或持续性活动,然后在应用返回后台时重新创建它们,但这并不是必需的。
暂停持续性活动
如果您的应用有明确的停止操作,请在取消暂停后让持续性活动继续。对于没有明确停止操作的应用,请在活动暂停时结束活动。
主要注意事项
使用 Ongoing Activity API 时,请注意以下几点:
请务必为持续性活动设置静态图标,显式设置或设置为使用 通知的回调均可。否则,您会收到
IllegalArgumentException。使用具有透明背景的黑白矢量图标。
请务必为持续性活动设置触摸 intent,显式设置或设置为使用通知的回调均可。否则,您会收到
IllegalArgumentException。如果应用在清单中声明了多个
MAIN LAUNCHERactivity,请发布一个 动态快捷方式,并使用LocusId将其与持续性活动相关联。
在 Wear OS 设备上播放媒体时发布媒体通知
如果媒体内容正在 Wear OS 设备上播放,请发布媒体 通知。这样,系统就可以创建相应的持续性活动。
如果您使用的是 Media3,系统会自动发布通知。如果您
手动创建通知,则该通知应使用
MediaStyleNotificationHelper.MediaStyle,并且相应的
MediaSession应填充其会话活动。
为你推荐
- 注意:当 JavaScript 处于关闭状态时,系统会显示链接文字
- 创建通知 {:#notification}
- 利用 Ongoing Activity API,以新的方式与 Wear OS 用户互动
- 创建展开式通知 {:#expandable-notification}