將 Android 小工具與 Google 助理整合

1. 總覽

第一個應用程式動作程式碼研究室中,您已瞭解如何實作「健康與健身 BII」類別的內建意圖 (BII),將 Google 助理擴充至範例健身應用程式。

應用程式動作可讓使用者直接透過 Google 助理啟動特定的應用程式功能,只要說出「Ok Google,在範例應用程式上開始跑步」這類指令即可。除了啟動應用程式,Google 助理也可以向使用者顯示互動式 Android 小工具,以執行符合資格的 BII。

畫面上的畫面顯示 Google 助理傳回小工具,回應使用者查詢觸發了應用程式 GET_EXERCISE_OBSERVATION BII 功能。

建構項目

在本程式碼研究室中,您將瞭解如何傳回 Android 小工具,以執行 Google 助理使用者要求。您也學到:

  • 用來打造個人化小工具的使用者 BII 參數。
  • 在 Google 助理中提供小工具的文字轉語音 (TTS) 簡介。
  • 使用內建意圖參考資料,判斷哪些 BII 支援小工具執行要求。

必要條件

繼續操作前,請先確保開發環境已準備好可以進行應用程式動作開發作業。其中應包含:

  • 用於執行殼層指令的終端機,且已安裝 Git。
  • 最新的 Android Studio 穩定版。
  • 可上網的實體或虛擬 Android 裝置。
  • 已登入 Android Studio、Google 應用程式和 Google 助理應用程式的 Google 帳戶。

如果您使用的是實體裝置,請將裝置連線至本機開發機器。

2. 瞭解運作方式

Google 助理會使用自然語言理解技術 (NLU) 讀取使用者的要求,並將該要求與 Google 助理內建意圖 (BII) 配對。接著,Google 助理會將意圖對應至實作 BII 的功能,也就是您在應用程式中註冊該意圖的功能。最後,Google 助理會使用功能中的詳細資料,顯示應用程式產生的 Android 小工具,藉此執行使用者的要求。

在本程式碼研究室中,您將定義註冊支援 GET_EXERCISE_OBSERVATION BII 的功能。在這項功能中,您將指示 Google 助理為 FitActions 小工具類別產生 Android 意圖,以執行此 BII 的要求。您可以更新這個類別,產生個人化的小工具供 Google 助理向使用者顯示,並對 Google 助理宣布的 TTS 簡介。

下圖說明這個流程:

說明 Google 助理小工具執行要求的流程圖。

FitActions 小工具

FitActions 範例應用程式提供健身資訊小工具,可讓使用者新增至主螢幕。這個小工具很適合用於執行會觸發 GET_EXERCISE_OBSERVATION BII 的使用者查詢。

小工具的運作方式

當使用者在主畫面中新增小工具時,小工具會對裝置進行連線偵測 (ping)。這項服務會從應用程式 AndroidManifest.xml 資源中的小工具接收器定義,擷取小工具相關資訊。系統會使用這項資訊產生代表小工具的 RemoteViews 物件。

範例應用程式會定義與 StatsWidgetProvider 類別對應的接收器 widgets.StatsWidgetProvider

<!-- app/src/main/AndroidManifest.xml -->

<receiver
  android:name=".widgets.StatsWidgetProvider"
  android:exported="false">
  <intent-filter>
    <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
  </intent-filter>
  <meta-data
    android:name="android.appwidget.provider"
    android:resource="@xml/stats_widget" />
</receiver>

StatsWidgetProvider 類別 StatsWidgetProvider.kt 會管理 StatsWidget 物件建立流程。這個程式庫可處理以下責任:

  • 建立小工具執行個體,並填入應用程式資料庫中的運動資料。
  • 使用 formatDataAndSetWidget() 設定健身資料格式,以便閱讀。
  • 如果無法取得健身資料,請使用 setNoActivityDataWidget() 提供預設值。

新增 Google 助理支援

在本程式碼研究室中,您將更新範例應用程式以處理應用程式動作功能。這些異動包括:

  1. 設定 GET_EXERCISE_OBSERVATION BII 功能,傳回 StatsWidget 物件的執行個體。
  2. 更新 StatsWidget 類別即可使用應用程式動作功能,例如:
    • 使用 BII 參數,讓使用者藉由詢問「Ok Google,在範例應用程式上顯示我的跑步統計資料」這類指令,來查看特定的健身統計資料。
    • 提供文字轉語音簡介字串。
    • 管理特殊情況,例如使用者查詢不含健身類型參數的時間。

3. 準備開發環境

下載基礎檔案

執行下列指令,複製範例應用程式的 GitHub 存放區

git clone --branch start-widget-codelab https://github.com/actions-on-google/appactions-fitness-kotlin.git

複製存放區後,請按照下列步驟在 Android Studio 中開啟:

  1. 在「Welcome to Android Studio」對話方塊中,按一下「Import project」
  2. 找出並選取您複製存放區的資料夾。

如要查看代表完成程式碼研究室的應用程式版本,請使用 --branch master 旗標複製範例應用程式存放區。

更新 Android 應用程式 ID

更新應用程式的應用程式 ID 可在測試裝置上辨識應用程式,避免「套件名稱重複」錯誤訊息。如要更新應用程式 ID,請開啟 app/build.gradle

android {
...
  defaultConfig {
    applicationId "com.MYUNIQUENAME.android.fitactions"
    ...
  }
}

取代「MYUNIQUENAME」在 applicationId 欄位中使用不重複的值。

安裝測試外掛程式

您可以利用 Google 助理外掛程式,在測試裝置上測試應用程式動作。這項功能的運作方式是透過 Android 裝置上的 Google 應用程式,將資訊傳送給 Google 助理。如果您尚未安裝外掛程式,請按照下列步驟安裝:

  1. 前往「File」>「Settings」 (在 MacOS 中則為「Android Studio」>「Preferences」)。
  2. 在「外掛程式」部分中,前往「Marketplace」並搜尋「Google 助理」。您也可以手動下載並安裝測試工具。
  3. 安裝工具,然後重新啟動 Android Studio。

在裝置上測試應用程式

對應用程式進行其他變更前,建議您先瞭解範例應用程式的功能。

在測試裝置上執行應用程式:

  1. 在 Android Studio 中,選取實體或虛擬裝置,然後依序選取「Run」>「Run app」,或按一下工具列中的「Run」在 Android Studio 中執行應用程式圖示。
  2. 長按主畫面按鈕,即可設定 Google 助理,並確認該功能是否正常運作。如果你尚未在裝置上登入 Google 助理,請先登入。

如要進一步瞭解 Android 虛擬裝置,請參閱「建立及管理虛擬裝置」。

簡短探索這個應用程式的功能。應用程式會預先填入 10 項運動活動,並在第一次檢視時顯示這項資訊。

試用現有小工具

  1. 輕觸「主畫面」按鈕,前往測試裝置的主畫面。
  2. 長按主畫面上的空白處,然後選取「小工具」
  3. 將小工具清單向下捲動至「FitActions」FitActions
  4. 長按 FitActions 圖示,然後將小工具放在主畫面上。

裝置主畫面上顯示 FitActions 小工具的螢幕截圖。

4. 新增應用程式動作

在這個步驟中,您將新增 GET_EXERCISE_OBSERVATION BII 功能。只要在 shortcuts.xml 中新增 capability 元素即可。這項功能會指定功能的觸發方式、如何使用 BII 參數,以及要叫用哪些 Android 意圖以完成要求。

  1. 使用以下設定,將 capability 元素新增至範例專案 shortcuts.xml 資源:
    <!-- fitnessactions/app/src/main/res/xml/shortcuts.xml -->
    
    <capability android:name="actions.intent.GET_EXERCISE_OBSERVATION">
      <app-widget
        android:identifier="GET_EXERCISE_OBSERVATION"
        android:targetClass="com.devrel.android.fitactions.widgets.StatsWidgetProvider"
        android:targetPackage="PUT_YOUR_APPLICATION_ID_HERE">
        <parameter
          android:name="exerciseObservation.aboutExercise.name"
          android:key="aboutExerciseName"
          android:required="true">
        </parameter>
        <extra android:name="hasTts" android:value="true"/>
      </app-widget>
      <!-- Add Fallback Intent-->
    </capability>
    
    android:targetPackage 值 (PUT_YOUR_APPLICATION_ID_HERE) 替換為您專屬的 applicationId

這項功能會將 GET_EXERCISE_OBSERVATION BII 對應至 app-widget 意圖,因此在觸發 BII 時,小工具會執行個體化並向使用者顯示。

觸發小工具前,Google 助理會從使用者的查詢內容中擷取支援的 BII 參數。本程式碼研究室需要 BII 參數 exerciseObservation.aboutExercise.name,代表使用者要求的運動類型。該應用程式支援三種運動類型:「跑步」、「步行」和「騎自行車」。您提供的內嵌目錄會向 Google 助理告知這些支援的值。

  1. 將這項設定 (位於 GET_EXERCISE_OBSERVATION 功能上方) 新增至 shortcuts.xml,即可定義這些庫存元素:
    <!-- shortcuts.xml -->
    
    <!-- shortcuts are bound to the GET_EXERCISE_OBSERVATION capability and
         represent the types of exercises supported by the app. -->
    
    <shortcut
      android:shortcutId="running"
      android:shortcutShortLabel="@string/activity_running">
      <capability-binding android:key="actions.intent.GET_EXERCISE_OBSERVATION">
        <parameter-binding
          android:key="exerciseObservation.aboutExercise.name"
          android:value="@array/runningSynonyms"/>
      </capability-binding>
    </shortcut>
    
    <shortcut
      android:shortcutId="walking"
      android:shortcutShortLabel="@string/activity_walking">
      <capability-binding android:key="actions.intent.GET_EXERCISE_OBSERVATION">
        <parameter-binding
          android:key="exerciseObservation.aboutExercise.name"
          android:value="@array/walkingSynonyms"/>
      </capability-binding>
    </shortcut>
    
    <shortcut
      android:shortcutId="cycling"
      android:shortcutShortLabel="@string/activity_cycling">
      <capability-binding android:key="actions.intent.GET_EXERCISE_OBSERVATION">
        <parameter-binding
          android:key="exerciseObservation.aboutExercise.name"
          android:value="@array/cyclingSynonyms"/>
      </capability-binding>
    </shortcut>
    
    <capability android:name="actions.intent.GET_EXERCISE_OBSERVATION">
      <!-- ... -->
    </capability>
    

新增備用意圖

備用意圖可處理使用者查詢因功能缺少必要參數而無法執行的情況。GET_EXERCISE_OBSERVATION 功能需要由 android:required="true" 屬性指定的 exerciseObservation.aboutExercise.name 參數。針對這類情況,你必須定義備用意圖,Google 助理才能成功處理要求,即使查詢中未提供參數也一樣。

  1. shortcuts.xml 中,使用以下設定為 GET_EXERCISE_OBSERVATION 功能新增備用意圖:
    <!-- shortcuts.xml -->
    
    <capability android:name="actions.intent.GET_EXERCISE_OBSERVATION">
    
      <app-widget>
        <!-- ... -->
      </app-widget>
    
      <!-- Fallback intent with no parameters needed to successfully execute.-->
      <intent
        android:identifier="GET_EXERCISE_OBSERVATION_FALLBACK"
        android:action="android.intent.action.VIEW"
        android:targetClass="com.devrel.android.fitactions.widgets.StatsWidgetProvider">
      </intent>
    </capability>
    

在這個範例設定中,備用執行要求是 Extra 資料中不含參數的 Android 意圖。

5. 啟用 Google 助理小工具

建立 GET_EXERCISE_OBSERVATION 功能後,請更新小工具類別,支援應用程式動作語音叫用。

新增小工具擴充功能程式庫

應用程式動作小工具擴充功能程式庫可強化小工具功能,提供語音導向的 Google 助理體驗。具體來說,就是為小工具提供自訂文字轉語音簡介。

  1. 將小工具擴充功能程式庫依附元件新增至範例應用程式 /app/build.gradle 資源:
    // app/build.gradle
    
    dependencies {
      //...
      implementation "com.google.assistant.appactions:widgets:0.0.1"
    }
    
    在 Android Studio 顯示的警告方塊中,按一下「Sync Now」。在每次 build.gradle 變更後同步,有助於避免建構應用程式時發生錯誤。

新增小工具服務

「服務」是可以在背景執行長時間執行作業的應用程式元件。應用程式必須提供能處理小工具要求的服務。

  1. 使用以下設定將服務新增至範例應用程式的 AndroidManifest.xml 資源:
    <!-- AndroidManifest.xml -->
    <service
       android:name=".widgets.StatsWidgetProvider"
       android:enabled="true"
       android:exported="true">
       <intent-filter>
           <action
               android:name="com.google.assistant.appactions.widgets.PIN_APP_WIDGET" />
       </intent-filter>
    </service>
    
    

執行小工具執行要求的語音查詢時,Google 助理會使用這項服務將要求傳送至應用程式。服務收到要求和 BII 資料。服務會使用這項資料產生 RemoteView 小工具物件,以便在 Google 助理內呈現。

更新小工具類別

應用程式現已設為將 GET_EXERCISE_OBSERVATION 功能要求轉送至小工具類別。接下來,請更新 StatsWidget.kt 類別,使用 BII 參數值產生根據使用者要求的個人化小工具例項。

  1. 開啟 StatsWidget.kt 類別,並匯入應用程式動作小工具擴充功能程式庫:
    // StatsWidget.kt
    
    // ... Other import statements
    import com.google.assistant.appactions.widgets.AppActionsWidgetExtension
    
    
  2. 新增以下不公開變數,即可判斷應填入小工具中的資訊:
    // StatsWidget.kt
    
    private val hasBii: Boolean
    private val isFallbackIntent: Boolean
    private val aboutExerciseName: String
    private val exerciseType: FitActivity.Type
    
  3. 新增 init 函式,讓類別使用從 Google 助理傳遞的小工具選項資料:
    // StatsWidget.kt
    
    init {
      val optionsBundle = appWidgetManager.getAppWidgetOptions(appWidgetId)
      val bii = optionsBundle.getString(AppActionsWidgetExtension.EXTRA_APP_ACTIONS_BII)
      hasBii = !bii.isNullOrBlank()
      val params = optionsBundle.getBundle(AppActionsWidgetExtension.EXTRA_APP_ACTIONS_PARAMS)
    
      if (params != null) {
        isFallbackIntent = params.isEmpty
        if (isFallbackIntent) {
          aboutExerciseName = context.resources.getString(R.string.activity_unknown)
        } else {
            aboutExerciseName = params.get("aboutExerciseName") as String
          }
      } else {
          isFallbackIntent = false
          aboutExerciseName = context.resources.getString(R.string.activity_unknown)
      }
      exerciseType = FitActivity.Type.find(aboutExerciseName)
    }
    
    

以下將逐步說明這些更新如何讓 StatsWidget.kt 類別回應 GET_EXERCISE_OBSERVATION 功能產生的 Android 意圖:

  • optionsBundle = 套裝組合
    • 組合是一種物件,用於跨程序邊界、包含意圖的活動,以及在設定變更時儲存暫時狀態。Google 助理會使用 Bundle 物件將設定資料傳遞至小工具。
  • bii = actions.intent.GET_EXERCISE_OBSERVATION
    • 使用 AppActionsWidgetExtension 可從套件取得 BII。
  • hasBii = true
    • 檢查是否有 BII。
  • params = Bundle[{aboutExerciseName=running}]
    • 由應用程式動作產生的特殊套件位於小工具選項 Bundle 中。其中包含 BII 的鍵/值組合,在本例中,值 running 是從範例查詢「Ok Google,顯示我的跑步統計資料」
  • isFallbackIntent = false
    • 檢查意圖 Extras 中是否存在必要的 BII 參數。
  • aboutExerciseName = running
    • 取得 aboutExerciseName 的意圖 Extras 值。
  • exerciseType = RUNNING
    • 使用 aboutExerciseName 查詢對應的資料庫類型物件。

現在 StatsWidget 類別可以處理收到的應用程式動作 Android 意圖資料,請更新小工具建立流程邏輯,檢查小工具是否由應用程式動作觸發。

  1. StatsWidget.kt 中,將 updateAppWidget() 函式替換為以下程式碼:
    // StatsWidget.kt
    
    fun updateAppWidget() {
       /**
        * Checks for App Actions BII invocation and if BII parameter data is present.
        * If parameter data is missing, use data from last exercise recorded to the
        *  fitness tracking database.
        */
       if (hasBii && !isFallbackIntent) {
           observeAndUpdateRequestedExercise()
       } else observeAndUpdateLastExercise()
    }
    
    

上述程式碼參照了 observeAndUpdateRequestedExercise 新函式。這個函式會使用應用程式動作 Android 意圖傳遞的 exerciseType 參數資料產生小工具資料。

  1. 使用以下程式碼新增 observeAndUpdateRequestedExercise 函式:
    // StatsWidget.kt
    
    /**
    * Create and observe the last exerciseType activity LiveData.
    */
    private fun observeAndUpdateRequestedExercise() {
      val activityData = repository.getLastActivities(1, exerciseType)
    
       activityData.observeOnce { activitiesStat ->
           if (activitiesStat.isNotEmpty()) {
               formatDataAndSetWidget(activitiesStat[0])
               updateWidget()
           } else {
               setNoActivityDataWidget()
               updateWidget()
           }
       }
    }
    
    

在上述程式碼中,使用應用程式中的現有 repository 類別,從應用程式的本機資料庫擷取健身資料。這個類別提供 API,簡化存取資料庫的流程。存放區的運作方式是,在對資料庫執行查詢時,公開 LiveData 物件。在程式碼中觀察此 LiveData,以擷取最新的健身活動。

啟用文字轉語音

你可以在顯示小工具時,提供 TTS 字串讓 Google 助理朗讀。建議您加入這些屬性,讓小工具能夠透過聲音顯示內容。這項功能是由「應用程式動作小工具」擴充功能程式庫提供,它可讓您設定與 Google 助理小工具相配的文字和 TTS 簡介。

如要提供 TTS 簡介,建議您使用 formatDataAndSetWidget 函式,以便設定應用程式資料庫傳回的活動資料格式。

  1. StatsWidget.kt 中,將下列程式碼新增至 formatDataAndSetWidget 函式中:
    // StatsWidget.kt
    
    private fun formatDataAndSetWidget(
      activityStat: FitActivity,
    ) {
          // ...
    
          // Add conditional for hasBii for widget with data
          if (hasBii) {
             // Formats TTS speech and display text for Assistant
             val speechText = context.getString(
                 R.string.widget_activity_speech,
                 activityExerciseTypeFormatted,
                 formattedDate,
                 durationInMin,
                 distanceInKm
             )
             val displayText = context.getString(
                 R.string.widget_activity_text,
                 activityExerciseTypeFormatted,
                 formattedDate
             )
             setTts(speechText, displayText)
          }
    }
    
    

上述程式碼參照了兩個字串資源:一個用於語音,另一個用於文字。如需文字轉語音推薦內容,請查看小工具影片的「文字轉語音建議」部分。此範例也參照 setTts,這是一個新函式,可將 TTS 資訊提供給小工具執行個體。

  1. 使用以下程式碼,將這個新的 setTts 函式新增至 StatsWidget.kt
    // StatsWidget.kt
    
    /**
     * Sets TTS to widget
     */
    private fun setTts(
      speechText: String,
      displayText: String,
    ) {
      val appActionsWidgetExtension: AppActionsWidgetExtension =
          AppActionsWidgetExtension.newBuilder(appWidgetManager)
            .setResponseSpeech(speechText)  // TTS to be played back to the user
            .setResponseText(displayText)  // Response text to be displayed in Assistant
            .build()
    
      // Update widget with TTS
      appActionsWidgetExtension.updateWidget(appWidgetId)
    }
    

最後,在運動資料庫針對要求的健身類型傳回空白資料時,設定 TTS 資訊以完成 TTS 邏輯。

  1. 使用以下程式碼更新 StatsWidget.kt 中的 setNoActivityDataWidget() 函式:
    // StatsWidget.kt
    
    private fun setNoActivityDataWidget() {
      // ...
      // Add conditional for hasBii for widget without data
      if (hasBii) {
        // formats speech and display text for Assistant
        // https://developers.google.com/assistant/app/widgets#library
        val speechText =
          context.getString(R.string.widget_no_activity_speech, aboutExerciseName)
        val displayText =
          context.getString(R.string.widget_no_activity_text)
    
        setTts(speechText, displayText)
      }
    }
    

6. 測試應用程式動作

在開發期間,請使用 Google 助理外掛程式,在測試裝置上預覽 Google 助理應用程式動作。您可以使用這項工具調整應用程式動作的意圖參數,以測試動作如何處理使用者要求 Google 助理執行該動作的各種方式。

製作試聽內容

如何使用外掛程式測試應用程式動作:

  1. 前往「工具」>Google 助理 >應用程式動作測試工具。系統可能會要求你使用 Google 帳戶登入 Android Studio。
  2. 按一下「Create Preview」。如果收到系統提示,請詳閱並接受應用程式動作政策和服務條款。

測試預期的運動類型

請在測試工具中按照下列步驟操作,傳回小工具,顯示上次在應用程式中完成的執行作業:

  1. 在工具要求您選取並設定 BII 的第一個步驟中,請選取 actions.intent.GET_EXERCISE_OBSERVATION
  2. 在「exerciseObservation」exerciseObservation方塊中,將預設運動名稱從 climbing 更新為 run
  3. 按一下「Run App Action」

螢幕顯示使用 Google 助理外掛程式傳回的小工具。

測試非預期的運動類型

如要在測試工具中測試非預期的運動類型:

  1. 在「exerciseObservation」exerciseObservation方塊中,將 name 值從 Run 更新為 Climbing
  2. 按一下「Run App Action」

Google 助理應傳回顯示「找不到活動」的小工具可能不準確或不適當

顯示小工具的畫面,其中沒有透過 Google 助理外掛程式傳回的運動資訊。

測試備用意圖

觸發備用意圖的查詢應傳回小工具,顯示任何運動類型的最近記錄活動相關資訊。

如何測試備用意圖:

  1. 在「exerciseObservation」exerciseObservation方塊中,刪除 aboutExercise 物件。
  2. 按一下「Run App Action」

Google 助理應會傳回小工具,顯示最後完成的運動。

螢幕顯示小工具,顯示最近使用 Google 助理外掛程式錄製的活動。

7. 後續步驟

恭喜!

您現在可以履行使用者Android 小工具中的 Google 助理查詢內容。

涵蓋內容

在本程式碼研究室中,您已瞭解如何:

  • 在 BII 中新增應用程式小工具。
  • 修改小工具以存取 Android Extras 的參數。

後續步驟

您可以從這裡嘗試進一步調整健身應用程式。如要參照完成的專案,請查看 GitHub 上的主要存放區

歡迎參考下列建議,進一步瞭解如何利用應用程式動作擴充這個應用程式:

  • 請參閱應用程式動作的內建意圖參考資料,探索更多將應用程式擴充至 Google 助理的方式。

如要繼續進行 Actions on Google 流程,請參閱下列資源:

在 Twitter 上追蹤 @ActionsOnGoogle,以隨時掌握最新公告,並透過 #appactions 使用 Twitter 分享自己的成果!

意見調查

最後,請填寫這份問卷,分享一下本程式碼研究室的使用體驗。