透過應用程式動作,將動態捷徑功能延伸至 Google 助理

1. 總覽

先前的程式碼研究室中,您已使用靜態捷徑,在範例應用程式中實作常用的內建意圖 (BII)。Android 開發人員會使用應用程式動作,將應用程式功能擴充至 Google 助理。

靜態捷徑已隨附於應用程式,因此只能透過發布應用程式的新版本來更新。要為應用程式中的動態元素 (例如使用者自製內容) 啟用語音功能,則必須使用動態捷徑。應用程式會在使用者執行相關動作後推送動態捷徑,例如在工作追蹤應用程式中建立新記事。透過應用程式動作,只要將這些捷徑繫結至 BII,即可透過 Google 助理存取語音內容,使用者只要說出「Ok Google,在範例應用程式上開啟我的雜貨清單」等指令即可。

三個漸進式畫面顯示 Google 助理啟動動態捷徑。

圖 1. 三個漸進式畫面顯示使用者建立的工作,Google 助理啟動了該工作項目的動態捷徑。

建構項目

在本程式碼研究室中,您將使用範例待辦事項清單 Android 應用程式啟用語音的動態捷徑,讓使用者可以要求 Google 助理開啟在應用程式中建立的工作清單項目。您可以使用 Android 架構模式完成這項操作,特別是存放區服務定位器ViewModel 模式。

必要條件

本程式碼研究室是以先前程式碼研究室介紹的應用程式動作概念為基礎,特別是 BII 和靜態捷徑。如果您是第一次使用應用程式動作,建議您先完成本程式碼研究室再繼續。

此外,請先確認開發環境具有以下設定,再繼續操作:

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

2. 瞭解運作方式

請按照下列步驟啟用語音存取的動態捷徑:

  • 將動態捷徑繫結至符合資格的 BII。
  • 新增 Google 捷徑整合資料庫,讓 Google 助理擷取捷徑。
  • 在使用者完成相關的應用程式內工作時推送捷徑。

繫結快速鍵

如要透過 Google 助理使用動態捷徑,該捷徑必須繫結至相關 BII。觸發含有捷徑的 BII 時,Google 助理會比對使用者要求中的參數與繫結捷徑中定義的關鍵字。例如:

  • 繫結至 GET_THING BII 的捷徑可讓使用者直接從 Google 助理要求特定應用程式內容。*「Ok Google,在範例應用程式中開啟我的雜貨清單。」
  • 繫結至 ORDER_MENU_ITEM BII 的捷徑可讓使用者重播過往訂單。*「Ok Google,使用範例應用程式照平常點餐。」

如需完整的 BII 分類清單,請參閱內建意圖參考資料

提供 Google 助理捷徑

將捷徑繫結至 BII 後,下一步就是在專案中新增 Google 捷徑整合程式庫,讓 Google 助理擷取這些捷徑。設定好這個程式庫後,Google 助理就會知道應用程式推送的每個快速鍵,讓使用者能透過 Google 助理的觸發指令詞組啟動這些捷徑。

3. 準備開發環境

本程式碼研究室會使用專為 Android 建構的範例待辦事項清單應用程式。使用者可以透過這個應用程式,將項目新增至清單、依類別搜尋工作清單項目,以及依完成狀態篩選工作。完成本節即可下載範例應用程式,並準備完成。

下載基礎檔案

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

git clone https://github.com/actions-on-google/app-actions-dynamic-shortcuts.git

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

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

或者,您也可以複製 GitHub 存放區的 codelab-complete 分支版本,藉此查看代表已完成程式碼研究室的範例應用程式版本:

git clone https://github.com/actions-on-google/app-actions-dynamic-shortcuts.git --branch codelab-complete

更新 Android 應用程式 ID

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

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

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

新增 Shortcuts API 依附元件

將下列 Jetpack 程式庫新增至 app/build.gradle 資源檔案:

app/build.gradle

dependencies {
   ...
   // Shortcuts library
   implementation "androidx.core:core:1.6.0"
   implementation 'androidx.core:core-google-shortcuts:1.0.1'
   ...
}

在裝置上測試應用程式

對應用程式進行其他變更前,建議您先瞭解範例應用程式的功能。如要在模擬器上執行應用程式,請按照下列步驟操作:

  1. 在 Android Studio 中,依序選取「Run」(執行) >執行應用程式,或按一下工具列中的「Run」在 Android Studio 中執行應用程式圖示
  2. 在「Select Deployment Target」對話方塊中,選取裝置,然後按一下「OK」。雖然應用程式動作適用於搭載 Android 5 (API 級別 21) 的裝置,但建議使用 Android 10 (API 級別 30) 以上版本。
  3. 長按主畫面按鈕,即可設定 Google 助理,並確認該功能是否正常運作。如果你尚未在裝置上登入 Google 助理,請先登入。

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

簡短探索這個應用程式的功能。輕觸「加號」圖示會建立一個新的工作項目,而右上方的選單項目則可讓您依完成狀態搜尋及篩選工作項目。

4. 建立捷徑存放區類別

範例應用程式中的幾個類別會呼叫 ShortcutManagerCompat API,以便推送及管理動態捷徑。為了減少程式碼的備援能力,您將實作存放區,讓專案類別輕鬆管理動態捷徑。

存放區設計模式提供簡潔的 API,可用來管理捷徑。存放區的優點在於基礎 API 的細節會在最小 API 背後完整擷取。請按照以下步驟實作存放區:

  1. 建立 ShortcutsRepository 類別來提取 ShortcutManagerCompat API。
  2. ShortcutsRepository 方法新增至應用程式的服務定位器
  3. 在主要應用程式中註冊 ShortcutRepository 服務。

建立存放區

com.example.android.architecture.blueprints.todoapp.data.source 套件中建立名為 ShortcutsRepository 的新 Kotlin 類別。你可以在 app/src/main/java 資料夾中找到這個套件。您將使用此類別實作一個介面,提供涵蓋程式碼研究室用途最精簡的方法組合。

Android Studio 視窗,顯示 ShortcutsRepository 類別的位置。

圖 2. Android Studio「Project Files」視窗顯示 ShortcutsRepository 類別的位置。

將下列程式碼貼入新類別中:

package com.example.android.architecture.blueprints.todoapp.data.source

import android.content.Context
import android.content.Intent
import androidx.annotation.WorkerThread
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import com.example.android.architecture.blueprints.todoapp.data.Task
import com.example.android.architecture.blueprints.todoapp.tasks.TasksActivity

private const val GET_THING_KEY = "q"

/**
* ShortcutsRepository provides an interface for managing dynamic shortcuts.
*/
class ShortcutsRepository(val context: Context) {

   private val appContext = context.applicationContext

   /**
    * Pushes a dynamic shortcut. The task ID is used as the shortcut ID.
    * The task's title and description are used as shortcut's short and long labels.
    * The resulting shortcut corresponds to the GET_THING capability with task's
    * title used as BII's "name" argument.
    *
    * @param task Task object for which to create a shortcut.
    */
   @WorkerThread
   fun pushShortcut(task: Task) {
      // TODO
   }

   private fun createShortcutCompat(task: Task): ShortcutInfoCompat {
      //...
   }

   /**
    *  Updates a dynamic shortcut for the provided task. If the shortcut
    *  associated with this task doesn't exist, this method throws an error.
    *  This operation may take a few seconds to complete.
    *
    * @param tasks list of tasks to update.
    */
   @WorkerThread
   fun updateShortcuts(tasks: List<Task>) {
       //...
   }

   /**
    * Removes shortcuts if IDs are known.
    *
    * @param ids list of shortcut IDs
    */
   @WorkerThread
   fun removeShortcutsById(ids: List<String>) {
       //...
   }

   /**
    * Removes shortcuts associated with the tasks.
    *
    * @param tasks list of tasks to remove.
    */
   @WorkerThread
   fun removeShortcuts(tasks: List<Task>) {
       //...
   }
}

接下來,請更新 pushShortcut 方法以呼叫 ShortcutManagerCompat API。使用下列程式碼更新 ShortcutsRepository 類別:

ShortcutsRepository.kt

/**
* Pushes a dynamic shortcut for the task. The task's ID is used as a shortcut
* ID. The task's title and description are used as shortcut's short and long
* labels. The created shortcut corresponds to GET_THING capability with task's
* title used as BII's "name" argument.
*
* @param task Task object for which to create a shortcut.
*/


@WorkerThread
fun pushShortcut(task: Task) {
   ShortcutManagerCompat.pushDynamicShortcut(appContext, createShortcutCompat(task))
}

在上述程式碼範例中,我們將 appContext 傳遞至 API。此為保存應用程式結構定義的類別屬性。為了避免記憶體流失,請務必使用應用程式情境 (而非活動情境),因為背景資料保留時間可能會超過主機活動生命週期。

此外,API 規定必須傳遞 Task 物件的 ShortcutInfoCompat 物件。在上述程式碼範例中,我們透過呼叫 createShortcutCompat 私人方法完成此操作,而該方法會更新為建立並傳回 ShortcutInfoCompat 物件。如要完成這項操作,請使用下列程式碼更新 createShortcutCompat 虛設常式:

ShortcutsRepository.kt

private fun createShortcutCompat(task: Task): ShortcutInfoCompat {
   val intent = Intent(appContext, TasksActivity::class.java)
   intent.action = Intent.ACTION_VIEW
   // Filtering is set based on currentTitle.
   intent.putExtra(GET_THING_KEY, task.title)

   // A unique ID is required to avoid overwriting an existing shortcut.
   return ShortcutInfoCompat.Builder(appContext, task.id)
           .setShortLabel(task.title)
           .setLongLabel(task.title)
           // Call addCapabilityBinding() to link this shortcut to a BII. Enables user to invoke a shortcut using its title in Assistant.
           .addCapabilityBinding(
                   "actions.intent.GET_THING", "thing.name", listOf(task.title))
           .setIntent(intent)
           .setLongLived(false)
       .build()
}

此類別中其餘的函式虛設常式可用於更新及刪除動態捷徑。使用下列程式碼更新即可啟用這些函式:

ShortcutsRepository.kt

/**
* Updates a Dynamic Shortcut for the task. If the shortcut associated with this task
* doesn't exist, throws an error. This operation may take a few seconds to complete.
*
* @param tasks list of tasks to update.
*/
@WorkerThread
fun updateShortcuts(tasks: List<Task>) {
   val scs = tasks.map { createShortcutCompat(it) }
   ShortcutManagerCompat.updateShortcuts(appContext, scs)
}

/**
* Removes shortcuts if IDs are known.
* @param ids list of shortcut IDs
*/
@WorkerThread
fun removeShortcutsById(ids: List<String>) {
   ShortcutManagerCompat.removeDynamicShortcuts(appContext, ids)
}

/**
* Removes shortcuts associated with the tasks.
*
* @param tasks list of tasks to remove.
*/
@WorkerThread
fun removeShortcuts(tasks: List<Task>) {
   ShortcutManagerCompat.removeDynamicShortcuts (appContext,
           tasks.map { it.id })
}

將類別新增至服務定位器

建立 ShortcutsRepository 類別後,下一步就是將這個類別的例項化物件提供給應用程式的其餘部分。此應用程式藉由實作服務定位器模式來管理類別依附元件。依序點選「Navigate」> > 即可使用 Android Studio 中的類別瀏覽器開啟服務定位器類別。Class 並輸入「ServiceLocator」。按一下產生的 Kotlin 檔案,即可在 IDE 中開啟該檔案。

ServiceLocator.kt 頂端貼上以下程式碼,以匯入 ShortcutsRepositorySuppressLint 套件:

ServiceLocator.kt

package com.example.android.architecture.blueprints.todoapp

// ...Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository
import android.annotation.SuppressLint

將下列程式碼貼入 ServiceLocator.kt 主體,以便新增 ShortcutRepository 服務成員和方法:

ServiceLocator.kt

object ServiceLocator {

   // ...
   // Only the code immediately below this comment needs to be copied and pasted
   // into the body of ServiceLocator.kt:

   @SuppressLint("StaticFieldLeak")
   @Volatile
   var shortcutsRepository: ShortcutsRepository? = null


   private fun createShortcutsRepository(context: Context): ShortcutsRepository {
       val newRepo = ShortcutsRepository(context.applicationContext)
       shortcutsRepository = newRepo
       return newRepo
   }

   fun provideShortcutsRepository(context: Context): ShortcutsRepository {
       synchronized(this) {
           return shortcutsRepository ?: shortcutsRepository ?: createShortcutsRepository(context)
       }
   }
 }

註冊捷徑服務

最後一步是向應用程式註冊新的「ShortcutsRepository」服務。在 Android Studio 中開啟 TodoApplication.kt,並複製接近檔案頂端的程式碼:

TodoApplication.kt

package com.example.android.architecture.blueprints.todoapp
/// ... Other import statements

import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository

接著,將下列程式碼新增至類別主體來註冊服務:

TodoApplication.kt

//...
class TodoApplication : Application() {

   //...

   val shortcutsRepository: ShortcutsRepository
       get() = ServiceLocator.provideShortcutsRepository(this)

   //...
}

建構應用程式,確保應用程式持續執行。

5. 推送新的捷徑

建立捷徑服務後,即可開始推送捷徑。由於使用者會在這個應用程式中產生內容 (工作項目),並期望稍後也能返回查看內容,因此每當使用者建立新工作時,我們都會推送繫結至 GET_THING BII 的動態捷徑,以便透過語音存取這項內容。這樣一來,使用者觸發 BII 時,Google 助理就能直接啟動他們要求的工作項目,例如「Ok Google,在 SampleApp 上開啟購物清單」

如要在範例應用程式中啟用這項功能,請完成下列步驟:

  1. ShortcutsRepository 服務匯入 AddEditTaskViewModel 類別,負責管理工作清單物件。
  2. 在使用者建立新工作時推送動態捷徑。

匯入 ShortcutsRepository

我們必須先為 AddEditTaskViewModel 提供 ShortcutsRepository 服務。如要完成這項作業,請將服務匯入 ViewModelFactory,也就是應用程式用來將 ViewModel 物件例項化的工廠類別,包括 AddEditTaskViewModel

依序前往「Navigate」> > 在 Android Studio 中開啟類別瀏覽器。Class 並輸入「ViewModelFactory」。按一下產生的 Kotlin 檔案,即可在 IDE 中開啟該檔案。

ViewModelFactory.kt 頂端貼上以下程式碼,以匯入 ShortcutsRepositorySuppressLint 套件:

ViewModelFactory.kt

package com.example.android.architecture.blueprints.todoapp

// ...Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository

接著,將 ViewModelFactory 的主體替換為以下程式碼:

ViewModelFactory.kt

/**
 * Factory for all ViewModels.
 */
@Suppress("UNCHECKED_CAST")
class ViewModelFactory constructor(
    private val tasksRepository: TasksRepository,
    private val shortcutsRepository: ShortcutsRepository,
    owner: SavedStateRegistryOwner,
    defaultArgs: Bundle? = null
) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {

    override fun <T : ViewModel> create(
        key: String,
        modelClass: Class<T>,
        handle: SavedStateHandle
    ) = with(modelClass) {
        when {
            isAssignableFrom(StatisticsViewModel::class.java) ->
                StatisticsViewModel(tasksRepository)
            isAssignableFrom(TaskDetailViewModel::class.java) ->
                TaskDetailViewModel(tasksRepository)
            isAssignableFrom(AddEditTaskViewModel::class.java) ->
                AddEditTaskViewModel(tasksRepository, shortcutsRepository)
            isAssignableFrom(TasksViewModel::class.java) ->
                TasksViewModel(tasksRepository, handle)
            else ->
                throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
        }
    } as T
}

向上移動一層以完成 ViewModelFactory 變更,並將 ShortcutsRepository 傳遞至工廠的建構函式。依序前往「Navigate」> > 開啟 Android Studio 的檔案瀏覽器。檔案,然後輸入「FragmentExt.kt」。按一下位於 util 套件中產生的 Kotlin 檔案,即可在 IDE 中開啟該檔案。

FragmentExt.kt 的主體替換為以下程式碼:

fun Fragment.getViewModelFactory(): ViewModelFactory {
   val taskRepository = (requireContext().applicationContext as TodoApplication).taskRepository
   val shortcutsRepository = (requireContext().applicationContext as TodoApplication).shortcutsRepository
   return ViewModelFactory(taskRepository, shortcutsRepository, this)
}

推送捷徑

透過範例應用程式的 ViewModel 類別可用的 ShortcutsRepository 抽象類別,您可以更新 AddEditTaskViewModel,也就是負責建立筆記的 ViewModel 類別,在使用者每次建立新記事時推送動態捷徑。

在 Android Studio 中開啟類別瀏覽器,然後輸入「AddEditTaskViewModel」。按一下產生的 Kotlin 檔案,即可在 IDE 中開啟該檔案。

首先,請使用下列匯入陳述式,將 ShortcutsRepository 套件新增至這個類別:

package com.example.android.architecture.blueprints.todoapp.addedittask

//Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository

接著,使用下列程式碼更新類別建構函式,即可加入 shortcutsRepository 類別屬性:

AddEditTaskViewModel.kt

//...

/**
* ViewModel for the Add/Edit screen.
*/
class AddEditTaskViewModel(
   private val tasksRepository: TasksRepository,
   private val shortcutsRepository: ShortcutsRepository
) : ViewModel() {

    //...

新增 ShortcutsRepository 類別後,請建立新函式 pushShortcut() 來呼叫此類別。將下列私有函式貼入 AddEditTaskViewModel 的主體:

AddEditTaskViewModel.kt

//...
private fun pushShortcut(newTask: Task) = viewModelScope.launch {
   shortcutsRepository.pushShortcut(newTask)
}

最後,每當建立工作時,推送新的動態捷徑。將 saveTask() 函式的內容替換為以下程式碼:

AddEditTaskViewModel.kt

fun saveTask() {
    val currentTitle = title.value
    val currentDescription = description.value

    if (currentTitle == null || currentDescription == null) {
        _snackbarText.value = Event(R.string.empty_task_message)
        return
    }
    if (Task(currentTitle, currentDescription).isEmpty) {
        _snackbarText.value = Event(R.string.empty_task_message)
        return
    }

    val currentTaskId = taskId
    if (isNewTask || currentTaskId == null) {
        val task = Task(currentTitle, currentDescription)
        createTask(task)
        pushShortcut(task)
    } else {
        val task = Task(currentTitle, currentDescription, taskCompleted, currentTaskId)
        updateTask(task)
    }
}

測試程式碼

我們終於可以測試程式碼了!在這個步驟中,你將推送支援語音的動態捷徑,並使用 Google 助理應用程式進行檢查。

製作試聽內容

使用 Google 助理外掛程式建立預覽,就能在測試裝置的 Google 助理中顯示動態捷徑。

安裝測試外掛程式

如果尚未安裝 Google 助理外掛程式,請按照下列步驟在 Android Studio 中安裝:

  1. 前往 **檔案 >「設定」(在 MacOS 中為「Android Studio」>「Preferences」)。
  2. 在「外掛程式」部分中,前往「Marketplace」並搜尋「Google 助理」。
  3. 安裝工具,然後重新啟動 Android Studio。

建立預覽

在 Android Studio 中,按照下列步驟建立預覽:

  1. 按一下「工具」>Google 助理 >「應用程式動作測試工具」。
  2. 在「應用程式名稱」方塊中定義名稱,例如「待辦事項清單」。
  3. 按一下「Create Preview」。如果收到系統提示,請詳閱並接受應用程式動作政策和服務條款。

應用程式動作測試工具預覽建立窗格。

圖 3. 應用程式動作測試工具預覽建立窗格。

在測試期間,你推送至 Google 助理的動態捷徑會顯示在 Google 助理中,並依據你為預先發布版提供的應用程式名稱分門別類。

推送及檢查捷徑

在測試裝置上重新啟動範例應用程式,然後執行下列步驟:

  1. 建立標題為「Start Codelab」的新工作
  2. 開啟 Google 助理應用程式,然後說出或輸入「我的捷徑」。
  3. 輕觸「探索」分頁標籤。畫面上應該會顯示捷徑範例。
  4. 輕觸快速鍵即可叫用。您應該會看到應用程式啟動,且快速鍵名稱已預先填入篩選器方塊,讓您更容易找到要求的工作項目。

6. (選用) 更新及刪除捷徑

除了在執行階段推送新的動態捷徑外,應用程式也可以更新捷徑,反映使用者內容和偏好設定的目前狀態。建議您在使用者修改目的地項目時更新現有的捷徑,例如重新命名範例應用程式中的工作。此外,每次移除目的地資源時,您也應該刪除對應的捷徑,以免向使用者顯示無效的捷徑。

更新捷徑

修改 AddEditTaskViewModel,在每次使用者變更工作項目的詳細資料時更新動態捷徑。首先,使用下列程式碼更新類別主體,新增使用存放區類別的更新函式:

AddEditTaskViewModel.kt

private fun updateShortcut(newTask: Task) = viewModelScope.launch {
   shortcutsRepository.updateShortcuts(listOf(newTask))
}

接下來,修改 saveTask() 函式,在每次更新現有工作時呼叫新方法。

AddEditTaskViewModel.kt

// Called when clicking on fab.
fun saveTask() {
   // ...
   // Note: the shortcuts are created/updated in a worker thread.
   if (isNewTask || currentTaskId == null) {
       //...
   } else {
       //...
       updateShortcut(task)
   }
}

請重新啟動應用程式,然後按照以下步驟測試程式碼:

  1. 將現有工作項目的標題重新命名為「完成程式碼研究室」。
  2. 說出「Ok Google,我的捷徑」來開啟 Google 助理。
  3. 輕觸「探索」分頁標籤。您應該會看到測試用捷徑的最新簡短標籤。

移除捷徑

使用者刪除工作時,應一併移除範例應用程式的捷徑。在範例應用程式中,工作刪除邏輯位於 TaskDetailViewModel 類別。更新這個類別之前,我們必須再次更新 ViewModelFactory,以便將 shortcutsRepository 傳遞至 TaskDetailViewModel

開啟 ViewModelFactory,將建構函式方法的內容換成以下程式碼:

//...
class ViewModelFactory constructor(
       private val tasksRepository: TasksRepository,
       private val shortcutsRepository: ShortcutsRepository,
       owner: SavedStateRegistryOwner,
       defaultArgs: Bundle? = null
) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {

   override fun <T : ViewModel> create(
           key: String,
           modelClass: Class<T>,
           handle: SavedStateHandle
   ) = with(modelClass) {
       when {
           isAssignableFrom(StatisticsViewModel::class.java) ->
               StatisticsViewModel(tasksRepository)
           isAssignableFrom(TaskDetailViewModel::class.java) ->
               TaskDetailViewModel(tasksRepository, shortcutsRepository)
           isAssignableFrom(AddEditTaskViewModel::class.java) ->
               AddEditTaskViewModel(tasksRepository, shortcutsRepository)
           isAssignableFrom(TasksViewModel::class.java) ->
               TasksViewModel(tasksRepository, handle)
           else ->
               throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
       }
   } as T
}

接著開啟 TaskDetailViewModel。匯入 ShortcutsRepository 模組,並使用下列程式碼宣告該模組的例項變數:

TaskDetailViewModel.kt

package com.example.android.architecture.blueprints.todoapp.taskdetail

...
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository


/**
* ViewModel for the Details screen.
*/
class TaskDetailViewModel(
       //...
       private val shortcutsRepository: ShortcutsRepository
   ) : ViewModel() {
...
}

最後,修改 deleteTask() 函式以呼叫 shortcutsRepository,在每次刪除具有對應 taskId 的工作時,根據其 ID 移除捷徑:

TaskDetailViewModel.kt

fun deleteTask() = viewModelScope.launch {
   _taskId.value?.let {
       //...
       shortcutsRepository.removeShortcutsById(listOf(it))
   }
}

如要測試程式碼,請重新啟動應用程式,然後按照下列步驟操作:

  1. 刪除測試工作。
  2. 將現有工作項目的標題重新命名為「完成程式碼研究室」。
  3. 說出「Ok Google,我的捷徑」來開啟 Google 助理。
  4. 輕觸「探索」分頁標籤。確認測試捷徑已經消失。

7. 後續步驟

恭喜!多虧了你的熱心協助,有了範例應用程式的使用者,只要對 Google 助理說出「Ok Google,在範例應用程式中開啟我的雜貨清單」,即可輕鬆返回自己建立的筆記。捷徑可讓使用者輕鬆重播常用的應用程式動作,進而有效提升使用者參與度。

涵蓋內容

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

  • 找出在應用程式中推送動態捷徑的用途。
  • 使用存放區、依附元件插入和服務定位器設計模式,降低程式碼的複雜度。
  • 將支援語音功能的動態捷徑推送至使用者產生的應用程式內容。
  • 更新及移除現有快速指令。

後續步驟

您可以嘗試進一步修正「工作清單」應用程式。如要參照完成的專案,請前往 GitHub 查看存放區 –codelab-complete 分支版本

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

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

在 Twitter 上追蹤 @ActionsOnGoogle,以隨時掌握最新公告消息;並透過 #appActions 推文分享你的傑出成果!

意見調查

最後,請填寫這份問卷調查,與我們分享您使用本程式碼研究室的感想。