使用 Ongoing Activity API 以新方式吸引 Wear OS 用户

1. 简介

a3457956a1735674.gif

观看上面的动画(Ongoing Activity 演示)。注意:动画 GIF 仅播放一次。如果您错过了动画,请重新加载页面。

从表盘上,您会注意到出现了一个动画图标(用于计时器),如果用户点击它,它会启动为计时器提供动力的应用程序。

**Ongoing Activity** 是 Wear OS 中的一项新功能,它允许 **Ongoing Notification** 在 Wear OS 用户界面中的其他界面上显示,从而使用户能够更多地参与长时间运行的活动。

**Ongoing Notification** 通常用于指示通知具有用户正在积极参与的后台任务(例如,播放音乐)或以某种方式挂起并因此占用设备(例如,文件下载、同步操作或活动网络连接)。

例如,Wear OS 用户可以使用计时器应用程序计时事件,然后从该应用程序导航到其他任务(查看天气、开始锻炼等)。

当用户从计时器应用程序导航离开时,该应用程序通常会过渡到与某些后台工作(服务、警报管理器等)相关的 **Ongoing Notification**,以让用户了解其计时器剩余的时间。

用户可以查看通知以获取更新,也可以与该通知进行交互。

但是,要查看通知,用户仍然需要在表盘下方滑动到通知托盘,并找到正确的通知,这不像其他界面那样方便。

使用 **Ongoing Activity** API,应用程序可以将信息公开到 Wear OS 上多个新的便捷界面,以保持用户的参与度。

以计时器应用程序为例,该信息可以显示在用户的表盘上,作为可点击的图标(**屏幕截图底部的活动指示器**)

b65ade9bf43c526e.png

计时器应用程序还可以显示在全局应用程序启动器中的“最近”部分,该部分列出所有 Ongoing Activity

1bc84dd2bd2d2b5d.png

全局启动器

最棒的是,您只需要添加大约 10 行代码即可完成!

您将学到什么

  • 创建和自定义 **Ongoing Activity**
  • 将 **Ongoing Activity** 绑定到 **Ongoing Notification**
  • 在设备/模拟器上测试 **Ongoing Activity**
  • 向您的 **Ongoing Activity** 添加交互(点击)

您将构建什么

您将使用自定义的 **Ongoing Activity** 扩展现有的“步行跟踪应用程序”,该活动在主表盘和应用程序启动器的“最近”部分显示活动步行的“步行积分”。

先决条件

2. 设置

在此步骤中,您将设置环境并下载入门项目。

您需要什么

  • Android Studio
  • Wear OS 模拟器(API 级别 >= 30)
  • Ongoing Activity 仅在 API 级别 30 或更高版本上可用
  • 模拟器新手?此处 是如何设置的。

下载代码

如果您安装了 git,您只需运行以下命令即可从 此仓库 克隆代码。要检查 git 是否已安装,请在终端或命令行中键入 git --version 并验证它是否能正常执行。

git clone https://github.com/android/codelab-ongoing-activity.git
cd ongoing-activity

如果您没有 git,您可以点击以下按钮下载此 codelab 的所有代码

您可以随时在 Android Studio 中运行任一模块,方法是更改工具栏中的运行配置。

b059413b0cf9113a.png

在 Android Studio 中打开项目

  1. 在“欢迎使用 Android Studio”窗口中,选择“打开”
  2. 选择文件夹 **[下载位置]**
  3. 当 Android Studio 导入项目后,测试您是否可以在 Wear OS 模拟器或物理设备上运行 startfinished 模块。
  4. start 模块应类似于下面的屏幕截图。您将在这里完成所有工作。

a40cc0c7e7e28bcf.png

通过开始步行锻炼来试用该应用程序。您应该注意到,您每隔 ~3 秒就会开始获得积分。(该应用程序使用模拟数据,因此您不必实际四处走动。)

尝试从应用程序中滑动退出。如果您导航到表盘下方的导航托盘,您应该能够找到继续跟踪您的步行积分的 Ongoing Notification。

点击它,它将显示如下

ac48b3ddc2a093bb.png

36fed11735ef4807.png

随意停止步行。

在本 code lab 结束时,相同的步行信息将显示在 **表盘** 和全局应用程序启动器的 **“最近”** 部分。

应用程序显示在表盘上(请参阅底部的 **活动指示器**)

59747518d70b053a.png

应用程序显示在 **应用程序启动器** 的“最近”部分

4817a55e6722629d.png

探索 start 代码

在 **start** 模块中

  • build.gradle 包含基本的应用程序配置。它包括创建 Ongoing Activity 所需的依赖项。
  • manifest > AndroidManifest.xml 包括将此标记为 Wear OS 应用程序所需的部分。
  • java > ... > data > WalkingWorkoutsRepository.kt 链接到 WalkingWorkoutsDataStore.kt 类,用于存储步行积分和步行锻炼的状态。不用担心细节,您不需要在此 code lab 中查看这些类。
  • java > ... > MainApplication.kt 创建仓库的单例。不用担心细节,您不需要在此 code lab 中查看这些类。
  • java > ... > ForegroundOnlyWalkingWorkoutService.kt 包含用于开始和停止步行锻炼的代码。如果锻炼处于活动状态且用户从应用程序中导航离开,它将从 Activity 解绑并启动 Ongoing Notification 以让用户了解其锻炼积分(使用模拟数据)。我们将在此处添加 Ongoing Activity 代码(靠近通知代码)。
  • java > ... > MainActivity.kt 包含用户界面,用于用户开始/停止步行锻炼。该活动绑定到上述服务,以便让该服务处理所有锻炼任务。
  • java > ... > MainViewModel.kt 是一个简单的 ViewModel,用于处理 MainActivity.kt 中的非 UI 代码。不用担心细节,您不需要在此 code lab 中查看这些类。

3. 查看应用程序

该应用程序已经是可以正常运行的步行锻炼应用程序。

正如您在前面的步骤中所见,您可以启动应用程序并开始/停止步行锻炼。在活动锻炼期间随着时间的推移,您会获得“步行积分”。

每次新的步行都会重置积分。

如果您在活动锻炼期间从应用程序中导航离开,您可以向下滑动以查看 **Ongoing Notification**,该通知会继续更新您的进度。

您可以从通知中停止锻炼,也可以打开应用程序。

通常,您会使用专有的算法根据位置和传感器数据计算“步行积分”。在本例中,我们只是模拟数据以简化操作。

它是如何工作的?

MainActivity 创建用户界面,链接到 ViewModel 以获取锻炼状态/步行积分的更新,并绑定到服务。

当锻炼开始或停止时,MainActivity 会调用服务中的开始或停止等效方法来处理跟踪锻炼的繁重工作。

如果用户导航离开,MainActivity 只需从服务解绑即可。

大部分魔力发生在 ForegroundOnlyWalkingWorkoutService 中。此类启动/停止锻炼并将所有状态或步行积分更改保存到仓库。

如果用户在会话期间从 MainActivity 导航离开,该服务也会转换为前台服务,并将自身绑定到一个 **持续通知**。

**持续通知** 继续跟踪锻炼工作,并绑定到上面的服务,作为前台服务。

如果您不了解所有细节,请不要担心。重要的是要理解这是一个功能齐全的应用程序,其通知已经构建完毕。我们只是想扩展该通知,使其通过 **持续活动** 在更多表面上可见。

该通知代码位于 ForegroundOnlyWalkingWorkoutService 中,您将在该文件中完成此代码实验室的所有工作。

4. 创建一个持续活动

查看依赖项

在此步骤中,我们不会编写代码。相反,我们将查看持续活动依赖项。

打开 start 模块中的 app/build.gradle 文件,并搜索 "TODO: Review dependencies for Ongoing Activity"。

您应该看到以下内容

步骤 1

    // TODO: Review dependencies for Ongoing Activity.
    implementation libs.androidx.wear.ongoing
    // Includes LocusIdCompat and new Notification categories for Ongoing Activity.
    implementation libs.androidx.core.ktx

第一个依赖项是使用 Wear OS 持续活动 API 所必需的。

第二个依赖项是为了获取通知 API 的最新功能,这些功能支持与持续活动结合使用的各种功能。以下两个功能可以应用于持续通知,因此也可以应用于持续活动。

  • 类别 - Android 使用一些预定义的系统范围类别来确定当用户启用了勿扰模式时,是否应使用给定通知打扰用户。类别确定持续活动在表盘上的优先级。最近添加了新的类别来支持 Wear。
  • LocusId - Locus 是 Android 10(API 级别 29)中引入的一个新概念,它使 Android 系统能够关联不同子系统之间的状态,例如内容捕获、快捷方式通知。如果您有多个启动器,可以使用 Locus ID 将持续活动绑定到特定的动态 快捷方式,以便它在应用程序启动器的最近部分中正确显示。

查看持续通知代码

在此步骤中,我们不会编写任何代码。相反,我们将只查看通知代码。

打开 start 模块中的 ForegroundOnlyWalkingWorkoutService.kt 文件,并搜索 "TODO: Review Notification builder code"。

您应该看到以下内容

步骤 2

// TODO: Review Notification builder code.
val notificationBuilder = notificationCompatBuilder
    .setStyle(bigTextStyle)
    .setContentTitle(titleText)
    .setContentText(mainText)
    .setSmallIcon(R.mipmap.ic_launcher)
    .setDefaults(NotificationCompat.DEFAULT_ALL)
    // Makes Notification an Ongoing Notification (a Notification with a background task).
    .setOngoing(true)
    // Android uses some pre-defined system-wide categories to determine whether to
    // disturb the user with a given notification when the user has enabled Do Not Disturb
    // mode. The Category determines the priority of the Ongoing Activity and new
    // categories were added recently to support Wear
    .setCategory(NotificationCompat.CATEGORY_WORKOUT)
    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
    .addAction(
        R.drawable.ic_walk, getString(R.string.launch_activity),
        activityPendingIntent
    )
    .addAction(
        R.drawable.ic_cancel,
        getString(R.string.stop_walking_workout_notification_text),
        servicePendingIntent
    )

// TODO: Create an Ongoing Activity.
// SKIP TODO FOR REVIEW STEP

return notificationBuilder.build()

查看上面的代码并阅读注释(跳过后面的 TODO 部分,那是后面的步骤)。

上面这部分代码中还有更多通知代码来设置此构建器。

但是,对于此代码实验室,我们只需要关注通知构建器中的 setOngoing() 调用和 setCategory()

类别有助于 Wear OS 确定表盘上通知的优先级。

setOngoing() 调用使我们的通知成为持续通知,即具有后台任务且用户正在积极参与的通知,例如跟踪步行锻炼。

当用户有活动步行锻炼并从 MainActivity 导航离开时,我们会创建此通知。

创建一个持续活动

**持续活动** 必须绑定到 **持续通知**。我们已经有了持续通知,所以现在让我们创建一个持续活动。

搜索 "TODO: Create an Ongoing Activity",并将 "// SKIP TODO FOR REVIEW STEP" 行替换为下面的代码。

步骤 4

// TODO: Create an Ongoing Activity.
val ongoingActivityStatus = Status.Builder()
    // Sets the text used across various surfaces.
    .addTemplate(mainText)
    .build()

val ongoingActivity =
    OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder)
        // Sets icon that will appear on the watch face in active mode. If it isn't set,
        // the watch face will use the static icon in active mode.
        .setAnimatedIcon(R.drawable.animated_walk)
        // Sets the icon that will appear on the watch face in ambient mode.
        // Falls back to Notification's smallIcon if not set. If neither is set,
        // an Exception is thrown.
        .setStaticIcon(R.drawable.ic_walk)
        // Sets the tap/touch event, so users can re-enter your app from the
        // other surfaces.
        // Falls back to Notification's contentIntent if not set. If neither is set,
        // an Exception is thrown.
        .setTouchIntent(activityPendingIntent)
        // In our case, sets the text used for the Ongoing Activity (more options are
        // available for timers and stop watches).
        .setStatus(ongoingActivityStatus)
        .build()

// Applies any Ongoing Activity updates to the notification builder.
// This method should always be called right before you build your notification,
// since an Ongoing Activity doesn't hold references to the context.
ongoingActivity.apply(applicationContext)

在创建持续活动之前,首先创建一个持续活动 Status,其中包含将在各种 Wear OS 表面上显示的文本。

我们使用 .addTemplate()Status.Builder 上设置文本,使其与我们用于通知的相同主文本。

您实际上可以自定义文本的外观(指定颜色、粗体等),但在此代码实验室中,我们将使文本保持简单。但是,如果您想了解更多信息,请阅读 持续活动指南

接下来,我们创建 OngoingActivity 本身。我们将上下文、通知 ID 以及我们在上面的代码中创建的通知构建器传递给 OngoingActivity.Builder() 的构造函数。

通知 ID 和 NotificationCompat.Builder 实例对于将 OngoingActivity 绑定到持续通知非常重要。

首先,我们设置一个动画图标(用于活动模式下的表盘)和一个静态图标(用于环境模式下的表盘)。

接下来,我们设置触摸事件,最后使用前面创建的 Status 对象设置文本,然后使用 .build() 关闭语句。

OngoingActivity 用户界面使用图标和 Status 的文本提供。触摸事件允许用户从表盘或全局应用程序启动器的最近部分点击返回应用程序。

最后,我们在持续活动上调用 apply() 并传递上下文。这是将持续活动中的任何更改应用于通知构建器的最后一步。

就这样,我们完成了!

notificationManager.notify(NOTIFICATION_ID, notification) 使用此通知被调用时,它现在将出现在新的表面上!

现在,在新的 Wear OS 模拟器或设备上运行您的应用程序。

从应用程序开始步行,然后滑动以退出应用程序。

在表盘上,您现在应该看到一个小小的步行人图标,如下所示(但动画化)。

59747518d70b053a.png

如果您点击该图标,您将返回应用程序!

再次退出应用程序,现在点击 Wear OS 设备上的应用程序启动器按钮。

您应该看到类似以下内容。

4817a55e6722629d.png

如果您点击最近部分中的步行应用程序,您应该再次进入应用程序!

5. 恭喜

恭喜!您学习了如何在 Wear OS 上构建持续活动!

持续活动是让用户在 Wear 中的全新表面上参与的一种绝佳方式。

接下来是什么?

查看其他 Wear OS 代码实验室

进一步阅读