1. סקירה כללית
ב-Codelab הקודם, השתמשת בקיצורי דרך סטטיים כדי להטמיע אובייקטים מובְנים מסוג Intent (BII) נפוצים באפליקציה לדוגמה. מפתחי Android משתמשים ב'פעולות באפליקציה' כדי להרחיב את הפונקציונליות של האפליקציה ל-Google Assistant.
קיצורי דרך סטטיים משויכים לאפליקציה, ואפשר לעדכן אותם רק כשמפרסמים גרסאות חדשות של האפליקציה. ניתן להפעיל את הפונקציונליות הקולית לרכיבים דינמיים באפליקציה, כמו תוכן שנוצר על ידי משתמשים, באמצעות קיצורי דרך דינמיים. אפליקציות דוחפות קיצורי דרך דינמיים אחרי שהמשתמשים מבצעים פעולות רלוונטיות, כמו יצירת הערה חדשה באפליקציית מעקב אחרי משימות. באמצעות 'פעולות באפליקציה', מפעילים את קיצורי הדרך האלה לפקודות קוליות על ידי קישור שלהם ל-BII, כך שהמשתמשים יכולים לגשת לתוכן שלהם מ-Assistant ולומר, למשל, "Ok Google, open my shopping list on ExampleApp".
איור 1. שלושה מסכים הדרגתיים שמוצגים בהם משימה שנוצרה על ידי משתמש, ו-Google Assistant מפעילה קיצור דרך דינמי לפריט הזה.
מה תפַתחו
ב-Codelab הזה, תפעילו קיצורי דרך דינמיים לקול באפליקציה לדוגמה של רשימת משימות ל-Android. כך המשתמשים יוכלו לבקש מ-Assistant לפתוח את הפריטים ברשימת המשימות שהם יוצרים באפליקציה. ניתן לעשות זאת באמצעות תבניות ארכיטקטורה של Android, במיוחד הדפוסים מאגר, מאתר השירות ו-ViewModel.
דרישות מוקדמות
ה-Codelab הזה מתבסס על המושגים של 'פעולות באפליקציה' שנלמדו בקוד Lab הקודם, במיוחד מזהי BII וקיצורי דרך סטטיים. אם עוד לא השתמשתם ב'פעולות באפליקציה', מומלץ להשלים את הפעולה הזו לפני שממשיכים.
בנוסף, לפני שממשיכים, צריך לוודא שבסביבת הפיתוח יש את ההגדרות הבאות:
- טרמינל להרצת פקודות מעטפת עם git מותקן.
- הגרסה היציבה האחרונה של Android Studio.
- מכשיר Android פיזי או וירטואלי עם גישה לאינטרנט.
- חשבון Google שמחובר ל-Android Studio, לאפליקציית Google ולאפליקציית Google Assistant.
2. איך זה עובד
כדי להפעיל קיצור דרך דינמי לגישה קולית באמצעות, יש לבצע את השלבים הבאים:
- קישור של קיצור דרך דינמי ל-BII שעומד בדרישות.
- לאפשר ל-Assistant להטמיע את קיצורי הדרך על ידי הוספת ספריית השילוב של Google קיצורי דרך.
- שליחת קיצור דרך בדחיפה בכל פעם שמשתמש משלים את המשימה הרלוונטית בתוך האפליקציה.
קיצורי דרך לקישור
כדי שקיצור דרך דינמי יהיה נגיש מ-Assistant, הוא צריך להיות מקושר ל-BII רלוונטי. כאשר מופעל BII עם קיצור דרך, Assistant מתאימה פרמטרים בבקשת המשתמש למילות מפתח שהוגדרו בקיצור הדרך. לדוגמה:
- קיצור דרך שמקושר ל-BII של
GET_THING
יכול לאפשר למשתמשים לבקש תוכן ספציפי בתוך האפליקציה, ישירות מ-Assistant. * "Hey Google, open my shopping list on ExampleApp". - קיצור דרך שמקושר ל-BII של
ORDER_MENU_ITEM
עלול לאפשר למשתמשים לבצע מחדש הזמנות קודמות. * "Ok Google, order my regular from ExampleApp".
לרשימה מלאה של מזהי BII אפשר לעיין בחומר העזר בנושא כוונות מובנות.
מספקים קיצורי דרך ל-Assistant
אחרי קישור קיצורי הדרך ל-BII, השלב הבא הוא לאפשר ל-Assistant להטמיע את קיצורי הדרך האלה על ידי הוספת ספריית השילוב של Google קיצורי דרך לפרויקט. כשהספרייה הזאת תהיה זמינה, Assistant תזהה את כל מקשי הקיצור שהאפליקציה שלך מפעילה, וכך המשתמשים יוכלו להפעיל את קיצורי הדרך האלה באמצעות ביטוי הטריגר של קיצור הדרך ב-Assistant.
3. הכנת סביבת הפיתוח
ה-Codelab הזה משתמש בדוגמה של אפליקציה עם רשימת משימות שמיועדת ל-Android. באמצעות האפליקציה הזו, משתמשים יכולים להוסיף פריטים לרשימות, לחפש פריטים ברשימת המשימות לפי קטגוריה ולסנן משימות לפי סטטוס ההשלמה. ממלאים את הסעיף הזה כדי להוריד ולהכין את האפליקציה לדוגמה.
הורדת הקבצים הבסיסיים
מריצים את הפקודה הבאה כדי לשכפל את מאגר GitHub של האפליקציה לדוגמה:
git clone https://github.com/actions-on-google/app-actions-dynamic-shortcuts.git
אחרי שמשכפלים את המאגר, פועלים לפי השלבים הבאים כדי לפתוח אותו ב-Android Studio:
- בתיבת הדו-שיח תחילת העבודה ב-Android Studio לוחצים על ייבוא פרויקט.
- בוחרים את התיקייה שאליה שכפול המאגר.
לחלופין אפשר להציג גרסה של האפליקציה לדוגמה שמייצגת את ה-Codelab שהושלם על ידי שכפול ההסתעפות codelab-complete
של מאגר ה-GitHub שלה:
git clone https://github.com/actions-on-google/app-actions-dynamic-shortcuts.git --branch codelab-complete
עדכון המזהה של האפליקציה ל-Android
עדכון מזהה האפליקציה של האפליקציה משמש לזיהוי ייחודי של האפליקציה במכשיר הבדיקה ולמניעת 'שם חבילה כפול'. שגיאה אם האפליקציה הועלתה ל-Play Console. כדי לעדכן את מזהה האפליקציה, פותחים את app/build.gradle
:
android {
...
defaultConfig {
applicationId "com.MYUNIQUENAME.android.fitactions"
...
}
}
מחליפים את "MYUNIQUENAME" בשדה applicationId
למשהו ייחודי לך.
הוספת יחסי תלות של קיצורי דרך ב-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'
...
}
בדיקת האפליקציה במכשיר
לפני שמבצעים שינויים נוספים באפליקציה, חשוב להבין מה אפשר לעשות באמצעות האפליקציה לדוגמה. כדי להפעיל את האפליקציה באמולטור שלכם, מבצעים את השלבים הבאים:
- ב-Android Studio, בוחרים באפשרות 'הפעלה' > מפעילים את האפליקציה או לוחצים על Run בסרגל הכלים.
- בתיבת הדו-שיח Select Deployment Target בוחרים מכשיר ולוחצים על OK. הגרסה המומלצת של מערכת ההפעלה היא Android 10 (רמת API 30) ואילך, אבל 'פעולות באפליקציה' פועלת במכשירים בגרסת Android 5 (רמת API 21).
- כדי להגדיר את Assistant ולוודא שהיא פועלת, לוחצים לחיצה ארוכה על הלחצן הראשי. אם עדיין לא עשית זאת, יהיה עליך להיכנס אל Assistant במכשיר שלך.
מידע נוסף על מכשירים וירטואליים של Android זמין במאמר יצירה וניהול של מכשירים וירטואליים.
בדקו בקצרה את האפליקציה כדי לראות מה היא יכולה לעשות. הקשה על סמל הפלוס יוצרת פריט חדש במשימה, ובעזרת האפשרויות בתפריט בפינה השמאלית העליונה אפשר לחפש ולסנן את המשימות לפי סטטוס ההשלמה.
4. יצירת מחלקה למאגר קיצורי דרך
חלק מהכיתות באפליקציה לדוגמה שלנו יקראו ל-API של ShortcutManagerCompat
כדי להעביר ולנהל קיצורי דרך דינמיים. כדי לצמצם את יתירות הקוד, תטמיעו מאגר כדי לאפשר למחלקות הפרויקטים לנהל בקלות קיצורי דרך דינמיים.
תבנית העיצוב של מאגר מספקת API נקי לניהול קיצורי דרך. היתרון של מאגר הוא שהפרטים של ה-API הבסיסי מופשטים באופן אחיד מאחורי API מינימלי. כדי להטמיע את המאגר:
- יוצרים מחלקה
ShortcutsRepository
כדי להפשט את ה-API שלShortcutManagerCompat
. - צריך להוסיף methods של
ShortcutsRepository
למאתר השירות של האפליקציה. - רישום השירות
ShortcutRepository
באפליקציה הראשית.
יצירת המאגר
יוצרים כיתת Kotlin חדשה בשם ShortcutsRepository
בחבילה com.example.android.architecture.blueprints.todoapp.data.source
. החבילה הזו מאורגנת בתיקייה app/src/main/java
. השיעור הזה ישמש אתכם כדי להטמיע ממשק שמספק קבוצה מינימלית של שיטות שמכסות את התרחיש לדוגמה שלנו ב-Codelab.
איור 2. חלון של קובצי פרויקט ב-Android Studio שמוצג בו מיקום המחלקה של 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>) {
//...
}
}
בשלב הבא, מעדכנים את ה-method pushShortcut
כדי להפעיל את ה-API של ShortcutManagerCompat
. מעדכנים את הכיתה 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 דורש שנעביר אובייקט ShortcutInfoCompat
עבור אובייקט המשימה. בדוגמת הקוד הקודמת, ניתן לעשות זאת באמצעות קריאה לשיטה הפרטית createShortcutCompat
, שאותה נעדכן כדי ליצור ולהחזיר אובייקט ShortcutInfoCompat
. כדי לעשות זאת, צריך לעדכן את ה-stub של 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()
}
שאר ה-stubs של הפונקציות בכיתה הזו עוסקים בעדכון ובמחיקה של קיצורי דרך דינמיים. כדי להפעיל את הפונקציות האלה, צריך לעדכן אותן באמצעות הקוד הבא:
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
, השלב הבא הוא להפוך את האובייקטים של המחלקה הזו לזמינים לשאר האפליקציה. האפליקציה הזו מנהלת את יחסי התלות של המחלקות על ידי הטמעת הדפוס מאתר השירות. כדי לפתוח את המחלקה של הכלי לאיתור שירותים באמצעות דפדפן הכיתה ב-Android Studio, עוברים אל ניווט > Class ומקישים על ServiceLocator. לוחצים על קובץ ה-Kotlin שנוצר כדי לפתוח אותו בסביבת הפיתוח המשולבת (IDE).
בחלק העליון של ServiceLocator.kt
, מדביקים את הקוד הבא כדי לייבא את החבילות ShortcutsRepository
ו-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
מוסיפים את רכיבי השירות ואת ה-methods ShortcutRepository
על ידי הדבקת הקוד הבא בגוף של 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)
}
}
}
רישום השירות של קיצורי הדרך
השלב האחרון הוא רישום של שירות 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. העברת קיצור דרך חדש בדחיפה
אחרי יצירת השירות לקיצורי הדרך, ניתן להתחיל להעביר קיצורי דרך. משתמשים יוצרים תוכן (פריטי משימה) באפליקציה הזו ומצפים שיוכלו לחזור אליהם מאוחר יותר, לכן כדי להפעיל את הגישה לתוכן הזה באופן קולי, נשלח קיצור דרך דינמי שמקושר ל-BII GET_THING
בכל פעם שמשתמש יוצר משימה חדשה. כך Assistant יכולה להפעיל את המשתמשים ישירות לפריט המשימה המבוקש כשהם מפעילים את ה-BII באמצעות פקודות כמו "Ok Google, open my shopping list on SampleApp".
כדי להפעיל את הפונקציונליות הזו באפליקציה לדוגמה, מבצעים את השלבים הבאים:
- ייבוא של השירות
ShortcutsRepository
למחלקהAddEditTaskViewModel
, שאחראי על ניהול אובייקטים של רשימות משימות. - דחיפת קיצור דרך דינמי כשהמשתמש יוצר משימה חדשה.
ייבוא של ShortcutsRepository
קודם אנחנו צריכים להפוך את השירות ShortcutsRepository
לזמין עבור AddEditTaskViewModel
. כדי לעשות זאת, מייבאים את השירות אל ViewModelFactory
, רמת היצרן שהאפליקציה משתמשת בה כדי ליצור אובייקטים של ViewModel, כולל AddEditTaskViewModel
.
פותחים את דפדפן הכיתה ב-Android Studio בקטע ניווט > כיתה וההקלדה של "ViewModel חוקיים". לוחצים על קובץ ה-Kotlin שנוצר כדי לפתוח אותו בסביבת הפיתוח המשולבת (IDE).
בחלק העליון של ViewModelFactory.kt
, מדביקים את הקוד הבא כדי לייבא את החבילות ShortcutsRepository
ו-SuppressLint
:
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
ל-constructor של המפעל. פותחים את הדפדפן לקבצים של Android Studio על ידי מעבר אל ניווט > קובץ מקלידים "FragmentExt.kt". לוחצים על קובץ ה-Kotlin שנוצר בחבילת ה-util כדי לפתוח אותו בסביבת הפיתוח המשולבת (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)
}
לחיצה על קיצור דרך
כשסיווג ההפשטה ShortcutsRepository
זמין לכיתות ViewModel
של האפליקציה לדוגמה, אתם מעדכנים את 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
על ידי עדכון ה-constructor של המחלקה בקוד הבא:
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 Assistant.
יצירת קטע מקדים
יצירת תצוגה מקדימה באמצעות הפלאגין של Google Assistant מאפשרת לקיצורי הדרך הדינמיים להופיע ב-Assistant במכשיר הבדיקה.
התקנת הפלאגין לבדיקה
אם עדיין לא התקנתם את הפלאגין של Google Assistant, צריך לבצע את הפעולות הבאות ב-Android Studio כדי להתקין אותו:
- מעבר אל **קובץ > 'הגדרות' (Android Studio > 'העדפות' ב-MacOS).
- בקטע יישומי פלאגין, עוברים אל Marketplace ומחפשים את 'Google Assistant'.
- אם אתם לא מוצאים את הפלאגין ב-Marketplace, מורידים אותו ידנית ופועלים לפי ההוראות במאמר התקנת הפלאגין מהדיסק.
- מתקינים את הכלי ומפעילים מחדש את Android Studio.
יצירת התצוגה המקדימה
כדי ליצור תצוגה מקדימה, מבצעים את השלבים הבאים ב-Android Studio:
- לוחצים על כלים > Google Assistant > "כלי הבדיקה של פעולות באפליקציה".
- בתיבה שם האפליקציה, מגדירים שם כמו "רשימת משימות".
- לוחצים על יצירת תצוגה מקדימה. אם מופיעה בקשה, קוראים את המדיניות ואת התנאים וההגבלות של 'פעולות באפליקציה' ומאשרים אותם.
איור 3. החלונית ליצירת תצוגה מקדימה של App Actions Test Tool.
במהלך הבדיקה, קיצורי דרך דינמיים שלוחצים על ה-Assistant מוצגים ב-Assistant לפי שם האפליקציה שסיפקתם בשביל התצוגה המקדימה.
דחיפת קיצור דרך ובדיקה שלו
מפעילים מחדש את האפליקציה לדוגמה במכשיר הבדיקה ומבצעים את השלבים הבאים :
- יוצרים משימה חדשה בשם 'Start Codelab'
- פותחים את אפליקציית Google Assistant ואומרים או מקלידים: "My shortcuts" (הקיצורי דרך שלי).
- מקישים על הכרטיסייה מה חדש. קיצור הדרך לדוגמה אמור להופיע.
- מקישים על קיצור הדרך כדי להפעיל אותו. כשתפעילו את האפליקציה, השם של קיצור הדרך אמור להופיע מראש בתיבת הסינון, כדי שיהיה לכם קל יותר למצוא את הפריט המבוקש.
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)
}
}
בודקים את הקוד על ידי הפעלה מחדש של האפליקציה וביצוע השלבים הבאים:
- משנים את השם של פריט המשימה הקיים ל-Finish Codelab.
- כדי לפתוח את Google Assistant, אומרים "Ok Google, my shortcuts".
- מקישים על הכרטיסייה מה חדש. אמורה להופיע תווית קצרה מעודכנת של קיצור הדרך לבדיקה.
הסרת קיצור דרך
אנחנו מסירים את הדוגמאות שלנו לקיצורי דרך של אפליקציות בכל פעם שמשתמש מוחק משימה. באפליקציה לדוגמה, הלוגיקה של מחיקת המשימה נמצאת במחלקה TaskDetailViewModel
. לפני שנעדכן את הכיתה הזו, עלינו לעדכן שוב את ההרשאה ViewModelFactory
כדי להעביר את shortcutsRepository
אל TaskDetailViewModel
.
פותחים את ViewModelFactory
ומחליפים את תוכן ה-method של ה-constructor בקוד הבא:
//...
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
תואמת:
TaskDetailViewModel.kt
fun deleteTask() = viewModelScope.launch {
_taskId.value?.let {
//...
shortcutsRepository.removeShortcutsById(listOf(it))
}
}
כדי לבדוק את הקוד, צריך להפעיל מחדש את האפליקציה ולפעול לפי השלבים הבאים:
- מוחקים את משימת הבדיקה.
- משנים את השם של פריט המשימה הקיים ל-Finish Codelab.
- כדי לפתוח את Google Assistant, אומרים "Ok Google, my shortcuts".
- מקישים על הכרטיסייה מה חדש. מוודאים שקיצור הדרך לבדיקה לא מופיע יותר.
7. השלבים הבאים
מזל טוב! בזכותך, משתמשי האפליקציה לדוגמה שלנו יכולים לחזור בקלות לפתקים שהם יצרו ולבקש מ-Assistant, למשל: "Ok Google, open my shopping list on ExampleApp". קיצורי דרך מעודדים מעורבות עמוקה יותר של המשתמשים כי הם מאפשרים למשתמשים לחזור בקלות על פעולות שהם עשו באפליקציה שלכם לעיתים קרובות.
אילו נושאים דיברנו?
ב-Codelab הזה למדת איך:
- לזהות תרחישים לדוגמה של דחיפת קיצורי דרך דינמיים באפליקציה.
- הפחתת את המורכבות של הקוד באמצעות דפוסי עיצוב של מאגר, החדרת תלות ותבניות תכנון של מאתר שירות (service locator).
- דחיפת קיצורי דרך דינמיים שמופעלים באמצעות קול לתוכן אפליקציה שנוצר על ידי משתמשים.
- לעדכן ולהסיר את קיצורי הדרך הקיימים.
מה השלב הבא?
מכאן אפשר לנסות לבצע שיפורים נוספים באפליקציה 'רשימת משימות'. כדי להפנות לפרויקט המוגמר, ראו הסתעפות Codelab-complete במאגר GitHub.
בהמשך מופיעות כמה הצעות ללמידה נוספת בנוגע להרחבת האפליקציה הזו באמצעות 'פעולות באפליקציה':
- כדאי לעיין בדוגמה של רשימת משימות לביצוע ב-Google Analytics for Firebase כדי ללמוד איך לעקוב אחר הביצועים של הפעולות באפליקציה.
- דרכים נוספות להרחבת האפליקציות ל-Assistant מפורטות בחומר העזר בנושא כוונות מובנות של 'פעולות באפליקציה'.
כדי להמשיך בתהליך שלך ב-Actions on Google, כדאי לעיין במקורות המידע הבאים:
- actions.google.com: אתר התיעוד הרשמי של Actions on Google.
- אינדקס לדוגמה של פעולות באפליקציה: אפליקציות וקוד לדוגמה לצורך התנסות ביכולות של 'פעולות באפליקציה'.
- פעולות במאגר GitHub של Google: קוד וספריות לדוגמה.
- r/GoogleAssistantDev: הקהילה הרשמית של Reddit למפתחים שעובדים עם Google Assistant.
אפשר לעקוב אחרינו ב- Twitter @ActionsOnGoogle כדי להתעדכן בהכרזות האחרונות, ולשלוח ציוץ אל #appActions כדי לשתף את מה שפיתחתם!
סקר משוב
לסיום, נמלא את הסקר הזה כדי לשלוח משוב על החוויה שלך עם Codelab.