1. Tổng quan
Trong lớp học lập trình trước, bạn đã sử dụng các lối tắt tĩnh để triển khai các ý định tích hợp (BII) thường dùng trong một ứng dụng mẫu. Nhà phát triển Android sử dụng Hành động trong ứng dụng để mở rộng chức năng của ứng dụng sang Trợ lý Google.
Lối tắt tĩnh được đi kèm với một ứng dụng và chỉ có thể cập nhật bằng cách phát hành các phiên bản mới của ứng dụng. Bạn có thể bật chức năng thoại cho các phần tử động trong một ứng dụng (chẳng hạn như nội dung do người dùng tạo) bằng cách sử dụng lối tắt động. Các ứng dụng sẽ đẩy lối tắt động sau khi người dùng thực hiện các hành động liên quan, chẳng hạn như tạo một ghi chú mới trong ứng dụng theo dõi công việc. Nhờ tính năng Hành động trong ứng dụng, bạn có thể bật các lối tắt này cho giọng nói bằng cách liên kết chúng với một BII, cho phép người dùng truy cập vào nội dung của họ từ Trợ lý bằng cách nói những câu như "Ok Google, hãy mở danh sách tạp hoá của tôi trên ExampleApp".

Hình 1. Ba màn hình tăng tiến cho thấy một việc cần làm do người dùng tạo và Trợ lý Google khởi chạy một lối tắt động đến việc cần làm đó.
Sản phẩm bạn sẽ tạo ra
Trong lớp học lập trình này, bạn sẽ bật lối tắt động cho giọng nói trong một ứng dụng Android mẫu về danh sách việc cần làm, cho phép người dùng yêu cầu Trợ lý mở các mục trong danh sách việc cần làm mà họ tạo trong ứng dụng. Bạn sẽ thực hiện việc này bằng cách sử dụng các mẫu cấu trúc Android, cụ thể là các mẫu repository (kho lưu trữ), service locator (trình định vị dịch vụ) và ViewModel (Mô hình hiển thị).
Điều kiện tiên quyết
Lớp học lập trình này dựa trên các khái niệm về Hành động trong ứng dụng được đề cập trong lớp học lập trình trước, đặc biệt là BII và lối tắt tĩnh. Nếu mới bắt đầu sử dụng Hành động trong ứng dụng, bạn nên hoàn thành lớp học lập trình đó trước khi tiếp tục.
Ngoài ra, hãy đảm bảo rằng môi trường phát triển của bạn có cấu hình sau đây trước khi tiếp tục:
- Một thiết bị đầu cuối để chạy các lệnh shell đã cài đặt git.
- Bản phát hành ổn định mới nhất của Android Studio.
- Một thiết bị Android thực hoặc thiết bị Android ảo có quyền truy cập Internet.
- Một Tài khoản Google đã đăng nhập vào Android Studio, ứng dụng Google và ứng dụng Trợ lý Google.
2. Tìm hiểu cách hoạt động
Để bật lối tắt động cho chế độ điều khiển bằng giọng nói, bạn cần thực hiện các bước sau:
- Liên kết một lối tắt động với một BII đủ điều kiện.
- Cho phép Trợ lý nhập các lối tắt bằng cách thêm Thư viện tích hợp lối tắt của Google.
- Đẩy một lối tắt bất cứ khi nào người dùng hoàn tất nhiệm vụ có liên quan trong ứng dụng.
Lối tắt liên kết
Để có thể truy cập vào một phím tắt động từ Trợ lý, bạn cần liên kết phím tắt đó với một BII có liên quan. Khi một BII có lối tắt được kích hoạt, Trợ lý sẽ so khớp các tham số trong yêu cầu của người dùng với các từ khoá được xác định trong lối tắt ràng buộc. Ví dụ:
- Một lối tắt được liên kết với BII
GET_THINGcó thể cho phép người dùng yêu cầu nội dung cụ thể trong ứng dụng, ngay từ Trợ lý. * "Ok Google, mở danh sách tạp hoá của tôi trên ExampleApp." - Một lối tắt được liên kết với BII
START_EXERCISEcó thể cho phép người dùng xem các phiên tập thể dục của họ. * "Ok Google, yêu cầu ExampleApp bắt đầu bài tập thể dục thường lệ của tôi."
Hãy tham khảo Tài liệu tham khảo về ý định tích hợp để xem danh sách đầy đủ các BII theo danh mục.
Cung cấp lối tắt cho Trợ lý
Sau khi liên kết các lối tắt với một BII, bước tiếp theo là cho phép Trợ lý nhập các lối tắt này bằng cách thêm Thư viện tích hợp lối tắt của Google vào dự án của bạn. Khi có thư viện này, Trợ lý sẽ biết từng lối tắt mà ứng dụng của bạn đẩy, cho phép người dùng chạy các lối tắt đó bằng cách sử dụng cụm từ kích hoạt của lối tắt trong Trợ lý.
3. Chuẩn bị môi trường phát triển
Lớp học lập trình này sử dụng một ứng dụng danh sách việc cần làm mẫu được tạo cho Android. Với ứng dụng này, người dùng có thể thêm các mục vào danh sách, tìm kiếm các mục trong danh sách việc cần làm theo danh mục và lọc các việc cần làm theo trạng thái hoàn thành. Tải xuống và chuẩn bị ứng dụng mẫu bằng cách hoàn tất phần này.
Tải tệp cơ sở xuống
Chạy lệnh sau để sao chép kho lưu trữ GitHub của ứng dụng mẫu:
git clone https://github.com/actions-on-google/app-actions-dynamic-shortcuts.git
Sau khi sao chép kho lưu trữ, hãy làm theo các bước sau để mở kho lưu trữ đó trong Android Studio:
- Trong hộp thoại Welcome to Android Studio (Chào mừng bạn đến với Android Studio), hãy nhấp vào Import project (Nhập dự án).
- Chọn thư mục mà bạn đã sao chép kho lưu trữ.
Ngoài ra, bạn có thể xem một phiên bản của ứng dụng mẫu đại diện cho lớp học lập trình đã hoàn thành bằng cách sao chép nhánh codelab-complete của kho lưu trữ Github:
git clone https://github.com/actions-on-google/app-actions-dynamic-shortcuts.git --branch codelab-complete
Cập nhật mã ứng dụng Android
Việc cập nhật mã ứng dụng của ứng dụng sẽ giúp nhận dạng duy nhất ứng dụng trên thiết bị thử nghiệm của bạn và tránh lỗi "Tên gói trùng lặp" nếu ứng dụng được tải lên Play Console. Để cập nhật mã ứng dụng, hãy mở app/build.gradle:
android {
...
defaultConfig {
applicationId "com.MYUNIQUENAME.android.fitactions"
...
}
}
Thay thế "MYUNIQUENAME" trong trường applicationId bằng một tên riêng biệt cho bạn.
Thêm các phần phụ thuộc Shortcuts API
Thêm các thư viện Jetpack sau vào tệp tài nguyên 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'
...
}
Kiểm thử ứng dụng trên thiết bị
Trước khi thực hiện thêm các thay đổi cho ứng dụng, bạn nên tìm hiểu xem ứng dụng mẫu có thể làm gì. Để chạy ứng dụng trên trình mô phỏng, hãy làm theo các bước sau:
- Trong Android Studio, hãy chọn Run > Run app (Chạy > Chạy ứng dụng) hoặc nhấp vào biểu tượng Run
(Chạy) trên thanh công cụ. - Trong hộp thoại Select Deployment Target (Chọn mục tiêu triển khai), hãy chọn một thiết bị rồi nhấp vào OK. Phiên bản hệ điều hành được đề xuất là Android 10 (cấp độ API 30) trở lên, mặc dù Hành động trong ứng dụng hoạt động trên thiết bị từ Android 5 (cấp độ API 21).
- Nhấn và giữ nút Màn hình chính để thiết lập Trợ lý và xác minh rằng Trợ lý hoạt động. Bạn sẽ cần đăng nhập vào Trợ lý trên thiết bị của mình (nếu chưa đăng nhập).
Để biết thêm thông tin về thiết bị ảo Android, hãy xem bài viết Tạo và quản lý thiết bị ảo.
Khám phá nhanh ứng dụng để xem những việc bạn có thể làm. Khi bạn nhấn vào biểu tượng Dấu cộng, một mục việc cần làm mới sẽ được tạo. Các mục trong trình đơn ở trên cùng bên phải cho phép bạn tìm kiếm và lọc các mục việc cần làm theo trạng thái hoàn thành.
4. Tạo một lớp kho lưu trữ lối tắt
Một số lớp trong ứng dụng mẫu của chúng tôi sẽ gọi API ShortcutManagerCompat để đẩy và quản lý các lối tắt động. Để giảm tình trạng dư thừa mã, bạn sẽ triển khai một kho lưu trữ để cho phép các lớp dự án dễ dàng quản lý các lối tắt động.
Mẫu thiết kế kho lưu trữ cung cấp một API không có lỗi để quản lý các lối tắt. Lợi thế của kho lưu trữ là thông tin chi tiết về API cơ bản được trừu tượng hoá một cách đồng nhất đằng sau một API tối thiểu. Triển khai kho lưu trữ bằng cách làm theo các bước sau:
- Tạo một lớp
ShortcutsRepositoryđể trừu tượng hoá APIShortcutManagerCompat. - Thêm các phương thức
ShortcutsRepositoryvào bộ định vị dịch vụ của ứng dụng. - Đăng ký dịch vụ
ShortcutRepositorytrong Ứng dụng chính.
Tạo kho lưu trữ
Tạo một lớp Kotlin mới có tên là ShortcutsRepository trong gói com.example.android.architecture.blueprints.todoapp.data.source. Bạn có thể tìm thấy gói này trong thư mục app/src/main/java. Bạn sẽ dùng lớp này để triển khai một giao diện cung cấp một bộ phương thức tối thiểu bao gồm trường hợp sử dụng trong lớp học lập trình của chúng ta.

Hình 2. Cửa sổ Project Files (Tệp dự án) của Android Studio cho biết vị trí của lớp ShortcutsRepository.
Dán mã sau vào lớp mới:
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>) {
//...
}
}
Tiếp theo, hãy cập nhật phương thức pushShortcut để gọi API ShortcutManagerCompat. Cập nhật lớp ShortcutsRepository bằng mã sau:
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))
}
Trong mẫu mã nêu trên, chúng ta đã truyền appContext đến API. Đây là một thuộc tính lớp chứa Ngữ cảnh ứng dụng. Bạn nên sử dụng Ngữ cảnh ứng dụng (thay vì Ngữ cảnh hoạt động) để tránh rò rỉ bộ nhớ, vì ngữ cảnh có thể được giữ lại lâu hơn vòng đời của activity lưu trữ.
Ngoài ra, API yêu cầu chúng ta truyền một đối tượng ShortcutInfoCompat cho đối tượng Task. Trong mẫu mã trước đó, chúng ta thực hiện việc này bằng cách gọi phương thức riêng tư createShortcutCompat. Chúng ta sẽ cập nhật phương thức này để tạo và trả về một đối tượng ShortcutInfoCompat. Để thực hiện việc này, hãy cập nhật phần khai báo createShortcutCompat bằng đoạn mã sau:
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()
}
Các phần còn lại của hàm trong lớp này liên quan đến việc cập nhật và xoá các lối tắt linh hoạt. Bật các hàm này bằng cách cập nhật chúng bằng mã sau:
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 })
}
Thêm lớp vào bộ định vị dịch vụ
Sau khi tạo lớp ShortcutsRepository, bước tiếp theo là cung cấp các đối tượng được khởi tạo của lớp này cho phần còn lại của ứng dụng. Ứng dụng này quản lý các phần phụ thuộc của lớp bằng cách triển khai mẫu công cụ định vị dịch vụ. Mở lớp công cụ định vị dịch vụ bằng trình duyệt lớp trong Android Studio bằng cách chuyển đến Navigate (Điều hướng) > Class (Lớp) rồi nhập "ServiceLocator". Nhấp vào tệp Kotlin vừa tạo để mở tệp đó trong IDE.
Ở đầu ServiceLocator.kt, hãy dán mã sau để nhập các gói ShortcutsRepository và SuppressLint:
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
Thêm các phương thức và thành phần dịch vụ ShortcutRepository bằng cách dán mã sau vào nội dung của ServiceLocator.kt:
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)
}
}
}
Đăng ký dịch vụ lối tắt
Bước cuối cùng là đăng ký dịch vụ ShortcutsRepository mới của bạn với Ứng dụng. Trong Android Studio, hãy mở TodoApplication.kt rồi sao chép đoạn mã sau vào gần đầu tệp:
TodoApplication.kt
package com.example.android.architecture.blueprints.todoapp
/// ... Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository
Tiếp theo, hãy đăng ký dịch vụ bằng cách thêm mã sau vào phần nội dung của lớp:
TodoApplication.kt
//...
class TodoApplication : Application() {
//...
val shortcutsRepository: ShortcutsRepository
get() = ServiceLocator.provideShortcutsRepository(this)
//...
}
Tạo ứng dụng và đảm bảo ứng dụng tiếp tục chạy.
5. Đẩy một lối tắt mới
Sau khi tạo dịch vụ lối tắt, bạn đã sẵn sàng bắt đầu đẩy các lối tắt. Vì người dùng tạo nội dung (mục việc cần làm) trong ứng dụng này và mong muốn có thể quay lại nội dung đó sau này, nên chúng tôi sẽ cho phép truy cập vào nội dung này bằng giọng nói bằng cách đẩy một lối tắt động được liên kết với BII GET_THING mỗi khi người dùng tạo một việc cần làm mới. Điều này cho phép Trợ lý đưa người dùng trực tiếp đến mục công việc mà họ yêu cầu khi họ kích hoạt BII bằng cách hỏi những câu như "Ok Google, mở danh sách tạp hoá của tôi trên SampleApp."
Bạn có thể bật chức năng này trong ứng dụng mẫu bằng cách hoàn tất các bước sau:
- Nhập dịch vụ
ShortcutsRepositoryvào lớpAddEditTaskViewModel, chịu trách nhiệm quản lý các đối tượng danh sách việc cần làm. - Đẩy một lối tắt động khi người dùng tạo một việc cần làm mới.
Nhập ShortcutsRepository
Trước tiên, chúng ta cần cung cấp dịch vụ ShortcutsRepository cho AddEditTaskViewModel. Để thực hiện việc này, hãy nhập dịch vụ vào ViewModelFactory, lớp factory mà ứng dụng dùng để tạo thực thể các đối tượng ViewModel, bao gồm cả AddEditTaskViewModel.
Mở trình duyệt lớp trong Android Studio bằng cách chuyển đến Navigate (Điều hướng) > Class (Lớp) rồi nhập "ViewModelFactory". Nhấp vào tệp Kotlin vừa tạo để mở tệp đó trong IDE.
Ở đầu ViewModelFactory.kt, hãy dán mã sau để nhập các gói ShortcutsRepository và SuppressLint:
ViewModelFactory.kt
package com.example.android.architecture.blueprints.todoapp
// ...Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository
Tiếp theo, hãy thay thế phần nội dung của ViewModelFactory bằng đoạn mã sau:
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
}
Hoàn tất các thay đổi ViewModelFactory bằng cách chuyển lên một lớp, rồi chuyển ShortcutsRepository đến hàm khởi tạo của nhà máy. Mở trình duyệt tệp của Android Studio bằng cách chuyển đến Navigate (Điều hướng) > File (Tệp) rồi nhập "FragmentExt.kt". Nhấp vào tệp Kotlin kết quả nằm trong gói util để mở tệp đó trong IDE.
Thay thế phần nội dung của FragmentExt.kt bằng đoạn mã sau:
fun Fragment.getViewModelFactory(): ViewModelFactory {
val taskRepository = (requireContext().applicationContext as TodoApplication).taskRepository
val shortcutsRepository = (requireContext().applicationContext as TodoApplication).shortcutsRepository
return ViewModelFactory(taskRepository, shortcutsRepository, this)
}
Đẩy một lối tắt
Với lớp trừu tượng ShortcutsRepository có sẵn cho các lớp ViewModel của ứng dụng mẫu, bạn sẽ cập nhật AddEditTaskViewModel, lớp ViewModel chịu trách nhiệm tạo ghi chú, để đẩy một lối tắt động mỗi khi người dùng tạo một ghi chú mới.
Trong Android Studio, hãy mở trình duyệt lớp rồi nhập "AddEditTaskViewModel". Nhấp vào tệp Kotlin vừa tạo để mở tệp đó trong IDE.
Trước tiên, hãy thêm gói ShortcutsRepository vào lớp này bằng câu lệnh nhập sau:
package com.example.android.architecture.blueprints.todoapp.addedittask
//Other import statements
import com.example.android.architecture.blueprints.todoapp.data.source.ShortcutsRepository
Tiếp theo, hãy thêm thuộc tính lớp shortcutsRepository bằng cách cập nhật hàm khởi tạo lớp bằng mã sau:
AddEditTaskViewModel.kt
//...
/**
* ViewModel for the Add/Edit screen.
*/
class AddEditTaskViewModel(
private val tasksRepository: TasksRepository,
private val shortcutsRepository: ShortcutsRepository
) : ViewModel() {
//...
Sau khi thêm lớp ShortcutsRepository, hãy tạo một hàm mới (pushShortcut()) để gọi lớp này. Dán hàm riêng tư sau vào nội dung của AddEditTaskViewModel:
AddEditTaskViewModel.kt
//...
private fun pushShortcut(newTask: Task) = viewModelScope.launch {
shortcutsRepository.pushShortcut(newTask)
}
Cuối cùng, hãy đẩy một lối tắt động mới mỗi khi một việc cần làm được tạo. Thay thế nội dung của hàm saveTask() bằng đoạn mã sau:
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)
}
}
Kiểm thử mã
Cuối cùng, chúng ta đã sẵn sàng kiểm thử mã của mình! Trong bước này, bạn sẽ đẩy một lối tắt động hỗ trợ giọng nói và kiểm tra lối tắt đó bằng ứng dụng Trợ lý Google.
Tạo bản xem trước
Việc tạo bản xem trước bằng trình bổ trợ Trợ lý Google cho phép các lối tắt động của bạn xuất hiện trong Trợ lý trên thiết bị thử nghiệm.
Cài đặt trình bổ trợ kiểm thử
Nếu bạn chưa có trình bổ trợ Trợ lý Google, hãy cài đặt trình bổ trợ này bằng cách làm theo các bước sau trong Android Studio:
- Chuyển đến **File > Settings (Tệp > Cài đặt) (Android Studio > Preferences (Lựa chọn ưu tiên) trên MacOS).
- Trong mục Plugins (Trình bổ trợ), hãy chọn Marketplace (Cửa hàng) rồi tìm "Google Assistant" (Trợ lý Google).
- Nếu bạn không tìm thấy trình bổ trợ này trên trang web thương mại, hãy tải trình bổ trợ xuống theo cách thủ công và làm theo hướng dẫn về cách Cài đặt trình bổ trợ từ ổ đĩa.
- Cài đặt công cụ rồi khởi động lại Android Studio.
Tạo bản xem trước
Tạo bản xem trước bằng cách làm theo các bước sau trong Android Studio:
- Nhấp vào Công cụ > Trợ lý Google > "Công cụ kiểm tra hành động trong ứng dụng".
- Trong hộp App name (Tên ứng dụng), hãy xác định một tên như "Todo List" (Danh sách việc cần làm).
- Nhấp vào Tạo bản xem trước. Nếu được yêu cầu, hãy xem xét và chấp nhận các chính sách và điều khoản dịch vụ về Hành động trong ứng dụng.

Hình 3. Ngăn tạo bản xem trước của Công cụ kiểm thử Hành động trong ứng dụng.
Trong quá trình kiểm thử, các lối tắt động mà bạn đẩy đến Trợ lý sẽ xuất hiện trong Trợ lý theo Tên ứng dụng mà bạn cung cấp cho bản xem trước.
Đẩy và kiểm tra một lối tắt
Khởi chạy lại ứng dụng mẫu trên thiết bị thử nghiệm và thực hiện các bước sau :
- Tạo một việc cần làm mới có tiêu đề "Bắt đầu lớp học lập trình"
- Mở ứng dụng Trợ lý Google rồi nói hoặc nhập: "Lối tắt của tôi".
- Nhấn vào thẻ Khám phá. Bạn sẽ thấy lối tắt mẫu.
- Nhấn vào lối tắt để gọi lối tắt đó. Bạn sẽ thấy ứng dụng khởi chạy với tên của lối tắt được điền sẵn trong hộp bộ lọc, giúp bạn dễ dàng tìm thấy mục công việc cần thiết.
6. (Không bắt buộc) Cập nhật và xoá lối tắt
Ngoài việc đẩy các lối tắt động mới trong thời gian chạy, ứng dụng của bạn có thể cập nhật các lối tắt này để phản ánh trạng thái hiện tại của nội dung và lựa chọn ưu tiên của người dùng. Bạn nên cập nhật các lối tắt hiện có bất cứ khi nào người dùng sửa đổi mục đích đến, chẳng hạn như đổi tên một việc cần làm trong ứng dụng mẫu của chúng tôi. Bạn cũng nên xoá lối tắt tương ứng bất cứ khi nào tài nguyên đích bị xoá để tránh hiển thị lối tắt bị hỏng cho người dùng.
Cập nhật lối tắt
Sửa đổi AddEditTaskViewModel để cập nhật lối tắt động bất cứ khi nào người dùng thay đổi thông tin chi tiết của một mục việc cần làm. Trước tiên, hãy cập nhật nội dung của lớp bằng mã sau để thêm một hàm cập nhật sử dụng lớp kho lưu trữ của chúng ta:
AddEditTaskViewModel.kt
private fun updateShortcut(newTask: Task) = viewModelScope.launch {
shortcutsRepository.updateShortcuts(listOf(newTask))
}
Tiếp theo, hãy sửa đổi hàm saveTask() để gọi phương thức mới của chúng ta bất cứ khi nào một tác vụ hiện có được cập nhật.
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)
}
}
Kiểm thử mã của bạn bằng cách khởi chạy lại ứng dụng và làm theo các bước sau:
- Đổi tên tiêu đề của mục việc cần làm hiện có thành "Hoàn thành lớp học lập trình".
- Mở Trợ lý Google bằng cách nói "Ok Google, lối tắt của tôi".
- Nhấn vào thẻ Khám phá. Bạn sẽ thấy nhãn ngắn mới cho Lối tắt thử nghiệm.
Xoá lối tắt
Bạn nên xoá các lối tắt của ứng dụng mẫu bất cứ khi nào người dùng xoá một việc cần làm. Trong ứng dụng mẫu, logic xoá nhiệm vụ nằm trong lớp TaskDetailViewModel. Trước khi cập nhật lớp này, chúng ta cần cập nhật lại ViewModelFactory để truyền shortcutsRepository vào TaskDetailViewModel.
Mở ViewModelFactory rồi thay thế nội dung của hàm khởi tạo bằng mã sau:
//...
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
}
Tiếp theo, hãy mở TaskDetailViewModel. Nhập mô-đun ShortcutsRepository và khai báo một biến thực thể cho mô-đun đó bằng mã sau:
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() {
...
}
Cuối cùng, hãy sửa đổi hàm deleteTask() để gọi shortcutsRepository nhằm xoá một lối tắt dựa trên mã nhận dạng của lối tắt đó bất cứ khi nào một tác vụ có taskId tương ứng bị xoá:
TaskDetailViewModel.kt
fun deleteTask() = viewModelScope.launch {
_taskId.value?.let {
//...
shortcutsRepository.removeShortcutsById(listOf(it))
}
}
Để kiểm thử mã, hãy khởi chạy lại ứng dụng và làm theo các bước sau:
- Xoá việc cần làm trong quá trình kiểm thử.
- Đổi tên tiêu đề của mục việc cần làm hiện có thành "Hoàn thành lớp học lập trình".
- Mở Trợ lý Google bằng cách nói "Ok Google, lối tắt của tôi".
- Nhấn vào thẻ Khám phá. Kiểm tra để đảm bảo lối tắt kiểm thử không còn xuất hiện.
7. Các bước tiếp theo
Xin chúc mừng! Nhờ bạn, người dùng ứng dụng mẫu của chúng tôi có thể dễ dàng quay lại những ghi chú mà họ tạo bằng cách hỏi Trợ lý những câu như "Ok Google, mở danh sách mua sắm của tôi trên ExampleApp". Lối tắt khuyến khích người dùng tương tác sâu hơn bằng cách giúp họ dễ dàng phát lại các hành động thường dùng trong ứng dụng của bạn.
Nội dung đã đề cập
Trong lớp học lập trình này, bạn đã tìm hiểu cách:
- Xác định các trường hợp sử dụng để đẩy lối tắt động trong một ứng dụng.
- Giảm độ phức tạp của mã bằng cách sử dụng mẫu thiết kế kho lưu trữ, tính năng chèn phần phụ thuộc và công cụ định vị dịch vụ.
- Đẩy các lối tắt động có hỗ trợ giọng nói đến nội dung ứng dụng do người dùng tạo.
- Cập nhật và xoá các lối tắt hiện có.
Bước tiếp theo
Từ đây, bạn có thể thử tinh chỉnh thêm cho ứng dụng Danh sách việc cần làm. Để tham khảo dự án đã hoàn thành, hãy xem nhánh –codelab-complete trên GitHub.
Sau đây là một số đề xuất để bạn tìm hiểu thêm về việc mở rộng ứng dụng này bằng Hành động trong ứng dụng:
- Hãy xem Mẫu danh sách việc cần làm bằng Google Analytics cho Firebase để tìm hiểu cách theo dõi hiệu suất của Hành động trong ứng dụng.
- Hãy truy cập vào tài liệu tham khảo về ý định tích hợp của Hành động trong ứng dụng để khám phá thêm nhiều cách mở rộng ứng dụng của bạn cho Trợ lý.
Để tiếp tục hành trình của bạn trên Actions on Google, hãy khám phá những tài nguyên sau:
- actions.google.com: Trang web tài liệu chính thức cho Actions on Google.
- Chỉ mục mẫu về Hành động trong ứng dụng: Ứng dụng và mã mẫu để khám phá các chức năng của Hành động trong ứng dụng.
- Kho lưu trữ Actions on Google trên GitHub: Mã mẫu và thư viện.
- r/GoogleAssistantDev: Cộng đồng Reddit chính thức dành cho các nhà phát triển làm việc với Trợ lý Google.
Theo dõi chúng tôi trên Twitter @ActionsOnGoogle để nắm bắt những thông báo mới nhất của chúng tôi, đồng thời đăng bài lên Twitter kèm thẻ hashtag #appActions để chia sẻ những gì bạn đã tạo!
Khảo sát nhận phản hồi
Cuối cùng, vui lòng điền vào khảo sát này để đưa ra ý kiến phản hồi về trải nghiệm của bạn với lớp học lập trình này.