透過 Ongoing Activity API 以全新的方式吸引 Wear OS 使用者

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

1. 簡介

cb2a383284f10acd.gif

觀看上方的動畫 (「持續進行的活動」示範影片)。注意:動畫 GIF 只能播放一次。如果您錯過動畫,請重新載入頁面。

錶面上會顯示動畫圖示 (代表計時器),如果使用者輕觸該圖示,支援計時器的應用程式就會啟動。

持續進行的活動是 Wear OS 的新功能,可讓 Wear OS 使用者介面中的其他介面顯示持續通知,提升使用者對於長時間執行活動的參與程度。

持續通知通常用於表示「通知」含有使用者積極參與 (例如播放音樂) 的背景工作,這類背景工作也有可能是以某種方式處於待處理的狀態,因此佔用了裝置 (例如檔案下載、同步處理作業或有效的網路連線)。

舉例來說,Wear OS 使用者可能會使用計時器應用程式來為活動計時,然後離開該應用程式以開始執行其他工作 (查看天氣、開始運動等)。

當使用者離開計時器應用程式時,應用程式通常會轉換成與某些背景工作 (服務、鬧鐘管理員等) 相關的持續通知,讓使用者掌握計時器上的剩餘時間。

使用者可以查看「通知」以取得最新資訊,也可以與「通知」互動。

不過,如果使用者要檢視「通知」,必須查看錶面下方的通知匣,並且找到適當的「通知」,因此操作方式不如其他介面方便。

應用程式可透過 Ongoing Activity API,在 Wear OS 全新方便的介面上顯示資訊,讓使用者保持參與。

在「計時器」應用程式的案例中,資訊能以可輕觸的圖示顯示在使用者的錶面上 (螢幕截圖底部的活動指標):

1fc8f1c0d0b5776d.png

「計時器」應用程式也會顯示在全域應用程式啟動器的「近期」部分,其中會列出所有「持續進行的活動」:

92926c4d6dc3aad5.png

全域啟動器

最棒的是,您只需要加入大約 10 行程式碼即可!

學習目標

  • 建立及自訂持續進行的活動
  • 持續進行的活動連結至持續通知
  • 在裝置/模擬器上測試持續進行的活動
  • 將互動新增至持續進行的活動 (輕觸)

建構目標

您需要擴充現有的「步行追蹤應用程式」,其中包含自訂的「持續進行的活動」,這會將有效步行的「步行點數」顯示在主要錶面上,以及應用程式啟動器的「近期」部分。

必要條件

2. 開始設定

在這個步驟中,您會設定環境並下載範例專案。

您需要準備的項目

  • Android Studio (Arctic Fox) 最新 Beta 版,包含 Wear OS 模擬器的「開發人員預覽版」
  • Wear OS 模擬器 (API 級別 >= 30)
  • 「持續進行的活動」僅適用於 API 級別 30 以上的版本
  • 第一次使用模擬器嗎?這裡有設定方式的說明。

下載程式碼

如果您已安裝 Git,只要執行下列指令即可複製這個存放區的程式碼。如要檢查 Git 是否已安裝完成,請在終端機或指令列中輸入 git --version 類型,並確認其可正確執行。

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

如果您沒有 Git,可以點選下方按鈕,以下載這個程式碼研究室的所有程式碼:

您可以隨時變更工具列的執行設定,以便在 Android Studio 中執行任一模組。

8a2e49d6d6d2609d.png

在 Android Studio 中開啟專案

  1. 在「Welcome to Android Studio」(歡迎使用 Android Studio) 視窗中,選取 1f5145c42df4129a.png「Open an Existing Project」(開啟現有專案)
  2. 選取資料夾 [Download Location]
  3. Android Studio 匯入專案後,請測試是否能在 Wear OS 模擬器或實體裝置上執行 startfinished 模組。
  4. start 模組應如以下螢幕截圖所示。您會在該處執行所有工作。

a3817357e22438af.png

開始步行運動,試試看這個應用程式。您應該會每隔 3 秒左右就會獲得點數。(這款應用程式使用模擬資料,因此您不需要實際走動)。

請嘗試將應用程式滑出。如果在錶面下方前往瀏覽匣,應該就能找到「持續通知」,以持續追蹤您的步行點數。

輕觸之後,看起來會像這樣:

990814a9f59a510a.png

ac59318b7243c403.png

您可以停止行走。

在這個程式碼研究室的結尾,「全域應用程式啟動器」的「錶面」以及「近期」部分會顯示相同的步行資訊。

錶面上顯示的應用程式 (請參閱底部的「活動指標」):

61112a8afe935eb5.png

在「應用程式啟動器」的「近期」部分顯示的應用程式:

717a9825221a8f86.png

探索範例程式碼

start 模組中:

  • build.gradle 包含基本的應用程式設定。其中包含建立「持續進行的活動」所需的依附元件。
  • manifest > AndroidManifest.xml 包含將其標示為 Wear OS 應用程式所需的部分。
  • java > ... > data > WalkingWorkoutsRepository.kt 會連結至 WalkingWorkoutsDataStore.kt 類別,以便儲存步行運動的點數和狀態。請放心,您不需要檢視程式碼研究室的這些類別。
  • java > ... > MainApplication.kt 會建立存放區的單例模式。請放心,您不需要檢視程式碼研究室的這些類別。
  • java > ... > ForegroundOnlyWalkingWorkoutService.kt 包含啟動和停止步行運動的程式碼。如果運動功能已啟用,而使用者離開應用程式,系統會解除應用程式與「活動」的連結,並啟動「持續通知」,讓使用者充分掌握運動點數 (會使用模擬資料)。這是用來新增「持續進行的活動」程式碼的位置 (位於「通知」程式碼附近)。
  • java > ... > MainActivity.kt 包含可讓使用者開始/停止步行運動的 UI。活動會與上述服務繫結,讓服務處理所有運動工作。
  • java > ... > MainViewModel.kt 是簡易的 ViewModel,可在 MainActivity.kt 中處理使用者介面以外的程式碼。請放心,您不需要檢視程式碼研究室的這些類別。

3. 查看應用程式

這個應用程式本身就是運作中的 Walking Workout 應用程式。

如同先前的步驟所述,您可以啟動應用程式,並開始/停止步行運動。在有效運動時,隨著時間經過,您會累積「步行點數」。

您可以為每一次的新步行重設點數。

如果您在有效運動期間離開應用程式,可以向下滑動以查看「持續通知」,以持續掌握進度。

您可以透過「通知」停止運動或是開啟應用程式。

一般而言,您可以使用專屬演算法來計算位置和感應器資料的「步行點數」。在這個案例中,我們只單純模擬資料,以便簡化操作。

運作方式

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 "androidx.wear:wear-ongoing:1.0.0-beta01"
    // Includes LocusIdCompat and new Notification categories for Ongoing Activity.
    implementation "androidx.core:core-ktx:1.6.0"

您必須具備第一個依附元件,才能使用 Wear OS Ongoing Activity API。

第二個依附元件是取得 Notification API 的最新功能,支援與「持續進行的活動」搭配使用的各種功能。下列兩項功能皆適用於「持續通知」,因此也可以套用至「持續進行的活動」:

  • 類別 - Android 會利用幾個預先定義的系統層級類別,判斷當使用者啟用勿擾模式時,是否要向使用者傳送指定的通知。「類別」可判斷錶面上「持續進行的活動」的優先順序。我們近期新增了更多類別,以支援 Wear。
  • LocusId - Locus 是 Android 10 (API 級別 29) 中引進的新概念,可讓 Android 系統連結不同子系統之間的狀態,例如內容擷取、「捷徑」和「通知」。如果您有多個啟動器,可以使用 Locus ID 將「持續進行的活動」連結至特定的動態目標 Shortcut,以便正確顯示在應用程式啟動器的「近期」部分。

查看「持續通知」程式碼

在這個步驟中,我們不會撰寫任何程式碼。相對地,我們只會審查「通知」程式碼。

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.
                // Supported animated icon types: AVD and AnimationDrawable.
                .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 介面上的文字。

我們是透過 Status.Builder 上的 .addTemplate() 將文字設為與「通知」相同的主要文字。

您可以自訂文字顯示的方式 (指定顏色、粗體等),但我們會讓這個程式碼研究室中的文字保持簡潔。如要瞭解詳情,請參閱「持續進行的活動」指南

接下來,我們要建立 OngoingActivity 本身。系統會將背景資訊、通知 ID 和程式碼上方建立的通知建構工具傳遞至 OngoingActivity.Builder() 的建構函式中。

通知 ID 和 NotificationCompat.Builder 執行個體很重要,用於將 OngoingActivity 連結至「持續通知」。

首先,我們要設定動畫圖示 (適用於正常模式的錶面) 和靜態圖示 (適用於微光模式的錶面)。

接著,我們要設定觸控事件,最後是使用先前建立的 Status 物件設定文字,再使用 .build() 結束陳述式。

系統會使用圖示和 Status 的文字提供 OngoingActivity 使用者介面。觸控事件可讓使用者透過錶面,或全球應用程式啟動器的「近期」部分,返回使用應用程式。

最後,我們會在「持續進行的活動」上活叫 apply(),並傳遞背景資訊。這個最後步驟會將「持續進行的活動」中的所有變更套用至通知建構工具。

這樣就完成了!

透過此「通知」呼叫 notificationManager.notify(NOTIFICATION_ID, notification) 時,會顯示在新的介面中!

現在,請在新的 Wear OS 模擬器或裝置上執行您的應用程式。

從應用程式啟動步行,滑動即可結束應用程式。

錶面上應該會顯示步行的人形小圖示 (如下所示,但應該是動畫):

61112a8afe935eb5.png

只要輕觸圖示,即可返回應用程式!

再次結束應用程式,然後輕觸 Wear OS 裝置上的應用程式啟動器按鈕。

如下所示:

717a9825221a8f86.png

如果您在「近期」部分中輕觸步行應用程式,就會再次進入應用程式!

5. 恭喜

恭喜!您已瞭解如何在 Wear OS 上建立「持續進行的活動」!

「持續進行的活動」是讓使用者在 Wear 的新介面上,與應用程式互動的好方法。

後續步驟

查看其他 Wear OS 程式碼研究室:

其他資訊