1. Обзор
В первой лаборатории кода App Actions вы узнали, как расширить Google Assistant до примера фитнес-приложения, реализовав встроенные намерения (BII) из категории BII «Здоровье и фитнес».
Действия приложения позволяют пользователям запускать определенные функции приложения напрямую из Ассистента, спрашивая что-то вроде: « Эй, Google, начни запуск в exampleApp». Помимо запуска приложений, Ассистент может отображать пользователю интерактивный виджет Android для выполнения запросов на соответствующие BII.
Что ты построишь
В этой лаборатории кода вы узнаете, как возвращать виджеты Android для выполнения запросов пользователей Ассистента. Вы также научитесь:
- Параметры пользовательского BII для персонализации виджетов.
- Обеспечьте преобразование текста в речь (TTS) в Ассистенте для своих виджетов.
- Используйте встроенную ссылку на намерение, чтобы определить, какие BII поддерживают выполнение виджета.
Предварительные условия
Прежде чем продолжить, убедитесь, что ваша среда разработки готова к разработке App Actions. Он должен иметь:
- Терминал для запуска команд оболочки с установленным git.
- Последняя стабильная версия Android Studio .
- Физическое или виртуальное устройство Android с доступом в Интернет.
- Учетная запись Google, в которой выполнен вход в Android Studio, приложение Google и приложение Google Assistant.
Если вы используете физическое устройство, подключите его к локальному компьютеру разработки.
2. Поймите, как это работает
Google Ассистент использует понимание естественного языка (NLU), чтобы прочитать запрос пользователя и сопоставить его со встроенным намерением Ассистента (BII). Затем Ассистент сопоставляет намерение с возможностью (реализующей BII), которую вы регистрируете для этого намерения в своем приложении. Наконец, Ассистент выполняет запрос пользователя, отображая виджет Android, который создает ваше приложение, используя сведения, найденные в этой возможности.
В этой лаборатории кода вы определяете возможность, которая регистрирует поддержку GET_EXERCISE_OBSERVATION
BII. Используя эту возможность, вы поручаете Ассистенту сгенерировать намерение Android для класса виджета FitActions
для выполнения запросов для этого BII. Вы обновляете этот класс, чтобы создать персонализированный виджет, который Помощник будет отображать пользователю, и введение TTS, которое будет объявлять Помощник.
Следующая диаграмма демонстрирует этот поток:
Виджет FitActions
Пример приложения FitActions содержит виджет с информацией о тренировках, который пользователи могут добавить на свой главный экран. Этот виджет является отличным кандидатом для выполнения пользовательских запросов, которые запускают GET_EXERCISE_OBSERVATION
BII.
Как работает виджет
Когда пользователь добавляет виджет на главный экран, виджет отправляет сигнал широковещательному приемнику устройства. Эта служба получает информацию о виджете из определения получателя виджета в ресурсе AndroidManifest.xml
приложения. Он использует эту информацию для создания объекта RemoteViews
представляющего виджет.
Пример приложения определяет получатель widgets.StatsWidgetProvider
, который соответствует классу 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()
.
Добавить поддержку Ассистента
В этой лаборатории кода вы обновите пример приложения для поддержки функций App Actions. Эти изменения включают в себя:
- Настройка возможности
GET_EXERCISE_OBSERVATION
BII для возврата экземпляра объектаStatsWidget
. - Обновление класса
StatsWidget
для использования таких функций App Actions, как:- Использование параметров BII, позволяющих пользователям просматривать конкретную статистику тренировок, задавая такие вопросы, как «Эй, Google, покажи мою статистику бега в exampleApp».
- Предоставление вводных строк TTS.
- Управление особыми случаями, например, когда пользовательский запрос не включает параметр типа тренировки.
3. Подготовьте среду разработки
Загрузите базовые файлы
Запустите эту команду, чтобы клонировать репозиторий GitHub примера приложения:
git clone --branch start-widget-codelab https://github.com/actions-on-google/appactions-fitness-kotlin.git
После клонирования репозитория выполните следующие действия, чтобы открыть его в Android Studio:
- В диалоговом окне «Добро пожаловать в Android Studio» нажмите «Импортировать проект» .
- Найдите и выберите папку, в которую вы клонировали репозиторий.
Чтобы увидеть версию приложения, представляющую завершенную кодовую работу, клонируйте репозиторий примера приложения, используя --branch master
.
Обновите идентификатор приложения Android
Обновление идентификатора приложения однозначно идентифицирует приложение на тестовом устройстве и позволяет избежать ошибки «Дублируется имя пакета», если приложение загружено в Play Console. Чтобы обновить идентификатор приложения, откройте app/build.gradle
:
android {
...
defaultConfig {
applicationId "com.MYUNIQUENAME.android.fitactions"
...
}
}
Замените «MYUNIQUENAME» в поле applicationId
на что-то уникальное для вас.
Установите тестовый плагин
Плагин Google Assistant позволяет тестировать действия приложения на тестовом устройстве. Он работает, отправляя информацию Ассистенту через приложение Google на вашем устройстве Android. Если у вас еще нет плагина, установите его, выполнив следующие действия:
- Перейдите в «Файл» > «Настройки» ( Android Studio > «Настройки» в MacOS).
- В разделе «Плагины» перейдите на Marketplace и найдите «Google Assistant». Вы также можете вручную загрузить и установить инструмент тестирования.
- Установите инструмент и перезапустите Android Studio.
Проверьте приложение на своем устройстве
Прежде чем вносить дополнительные изменения в приложение, полезно получить представление о том, на что способен пример приложения.
Запустите приложение на тестовом устройстве:
- В Android Studio выберите физическое или виртуальное устройство и выберите «Выполнить» > «Выполнить приложение» или нажмите «Выполнить». на панели инструментов.
- Нажмите и удерживайте кнопку «Домой», чтобы настроить Ассистента и убедиться, что он работает. Вам нужно будет войти в Ассистент на своем устройстве, если вы еще этого не сделали.
Дополнительную информацию о виртуальных устройствах Android см. в разделе Создание виртуальных устройств и управление ими .
Кратко изучите приложение, чтобы узнать, на что оно способно. Приложение предварительно заполняет 10 упражнений и отображает эту информацию в первом представлении.
Попробуйте существующий виджет
- Нажмите кнопку «Домой» , чтобы перейти на главный экран тестового устройства.
- Нажмите и удерживайте пустое место на главном экране и выберите «Виджеты» .
- Прокрутите список виджетов до FitActions .
- Нажмите и удерживайте значок FitActions и поместите его виджет на главный экран.
4. Добавьте действие приложения.
На этом этапе вы добавляете возможность GET_EXERCISE_OBSERVATION
BII. Это можно сделать, добавив новый элемент capability
в shortcuts.xml
. Эта возможность определяет, как эта возможность активируется, как используются параметры BII и какой Android намерен вызвать для выполнения запроса.
- Добавьте новый элемент
capability
в пример ресурсаshortcuts.xml
проекта.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 виджет создается и отображается пользователю.
Прежде чем активировать виджет, Ассистент извлекает поддерживаемые параметры BII из запроса пользователя. Для этой лаборатории кода требуется параметр BII exerciseObservation.aboutExercise.name
, который представляет запрошенный пользователем тип упражнения. Приложение поддерживает три типа упражнений: «бег», «ходьба» и «езда на велосипеде». Вы предоставляете встроенную инвентаризацию , чтобы информировать Ассистента об этих поддерживаемых значениях.
- Определите эти элементы инвентаря, добавив эту конфигурацию над возможностью
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
требуется параметр exerciseObservation.aboutExercise.name
, указанный атрибутом android:required="true"
. В таких ситуациях Ассистент требует, чтобы вы определили резервное намерение, чтобы обеспечить успешное выполнение запроса, даже если в запросе не указаны параметры.
- В
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>
В этом примере конфигурации резервное выполнение — это намерение Android без параметров в Extra
данных.
5. Включите виджет для Ассистента.
Установив возможность GET_EXERCISE_OBSERVATION
, обновите класс виджета, чтобы он поддерживал голосовой вызов действий приложения.
Добавьте библиотеку расширений виджетов
Библиотека расширений виджетов действий приложений расширяет возможности виджетов для голосового помощника. В частности, он позволяет вам предоставить собственное представление TTS для ваших виджетов.
- Добавьте зависимость библиотеки расширения виджетов к ресурсу примера приложения
/app/build.gradle
: Нажмите «Синхронизировать сейчас» в окне предупреждения, которое появляется в Android Studio. Синхронизация после каждого изменения// app/build.gradle dependencies { //... implementation "com.google.assistant.appactions:widgets:0.0.1" }
build.gradle
помогает избежать ошибок при сборке приложения.
Добавьте сервис виджетов
Служба — это компонент приложения, который может выполнять длительные операции в фоновом режиме. Ваше приложение должно предоставлять сервис для обработки запросов виджетов.
- Добавьте службу в ресурс
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>
Во время голосового запроса, который запускает выполнение виджета, Ассистент использует эту службу для отправки запросов в приложение. Служба получает запрос вместе с данными BII. Служба использует эти данные для создания объекта виджета RemoteView
для отображения в Assistant.
Обновите класс виджета
Теперь ваше приложение настроено на маршрутизацию запросов возможностей GET_EXERCISE_OBSERVATION
в класс вашего виджета. Затем обновите класс StatsWidget.kt
, чтобы сгенерировать экземпляр виджета, персонализированный в соответствии с запросом пользователя, используя значения параметров BII.
- Откройте класс
StatsWidget.kt
и импортируйте библиотеку расширений виджета действий приложения:// StatsWidget.kt // ... Other import statements import com.google.assistant.appactions.widgets.AppActionsWidgetExtension
- Добавьте эти частные переменные, которые вы используете при определении информации, которая должна заполнить виджет:
// StatsWidget.kt private val hasBii: Boolean private val isFallbackIntent: Boolean private val aboutExerciseName: String private val exerciseType: FitActivity.Type
- Добавьте функцию
init
, чтобы позволить классу использовать данные параметров виджета, переданные из Ассистента:// 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
реагировать на намерения Android, генерируемые возможностью GET_EXERCISE_OBSERVATION
:
-
optionsBundle
= Пакет- Пакеты — это объекты, которые предназначены для использования за пределами границ процесса, между действиями с намерениями и для хранения переходного состояния при изменениях конфигурации. Помощник использует объекты
Bundle
для передачи данных конфигурации в виджет.
- Пакеты — это объекты, которые предназначены для использования за пределами границ процесса, между действиями с намерениями и для хранения переходного состояния при изменениях конфигурации. Помощник использует объекты
-
bii
=actions.intent.GET_EXERCISE_OBSERVATION
- Имя BII можно получить из пакета с помощью
AppActionsWidgetExtension
.
- Имя BII можно получить из пакета с помощью
-
hasBii
=true
- Проверяет наличие BII.
-
params
=Bundle[{aboutExerciseName=running}]
- Специальный Bundle, созданный App Actions, вложен в параметры виджета
Bundle
. Он содержит пары ключ/значение BII. В этом случае значениеrunning
было извлечено из примера запроса «Эй, Google, покажи мою статистику бега в exampleApp».
- Специальный Bundle, созданный App Actions, вложен в параметры виджета
-
isFallbackIntent
=false
- Проверяет наличие необходимых параметров BII в намерении
Extras
.
- Проверяет наличие необходимых параметров BII в намерении
-
aboutExerciseName
=running
- Получает значение намерения
Extras
дляaboutExerciseName
.
- Получает значение намерения
-
exerciseType
=RUNNING
- Использует
aboutExerciseName
для поиска соответствующего объекта типа базы данных.
- Использует
Теперь, когда класс StatsWidget
может обрабатывать входящие данные о намерениях действий приложения Android, обновите логику потока создания виджета, чтобы проверить, был ли виджет запущен действием приложения.
- В
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
. Эта функция генерирует данные виджета, используя данные параметра exerciseType
, передаваемые намерением App Actions Android.
- Добавьте функцию
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() } } }
В приведенном выше коде используйте существующий класс репозитория , найденный в приложении, для получения данных о фитнесе из локальной базы данных приложения. Этот класс предоставляет API, упрощающий доступ к базе данных. Репозиторий работает, предоставляя объект LiveData при выполнении запросов к базе данных. В своем коде вы наблюдаете за этими LiveData
, чтобы получать последние данные о фитнес-тренировках.
Включить TTS
Вы можете предоставить строку TTS, чтобы Помощник мог объявлять ее при отображении виджета. Мы рекомендуем включить это, чтобы обеспечить звуковой контекст для ваших виджетов. Эта функциональность обеспечивается библиотекой расширений виджетов действий приложения, которая позволяет вам устанавливать текст и TTS-знакомства, сопровождающие ваши виджеты в Ассистенте.
Хорошим местом для ознакомления с TTS является функция formatDataAndSetWidget
, которая форматирует данные о действиях, возвращаемые из базы данных приложения.
- В
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) } }
Приведенный выше код ссылается на два строковых ресурса: один для речи, а другой для текста. Ознакомьтесь с рекомендациями по стилю преобразования текста в речь в нашем видеоролике о виджетах, чтобы получить рекомендации TTS. В примере также упоминается setTts
— новая функция, которая предоставляет информацию TTS экземпляру виджета.
- Добавьте эту новую функцию
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, когда база данных упражнений возвращает пустые данные для запрошенного типа тренировки.
- Обновите функцию
setNoActivityDataWidget()
вStatsWidget.kt
с помощью этого кода:// 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 Assistant для предварительного просмотра действий приложения Assistant на тестовом устройстве. Вы можете настроить параметры намерения для действия приложения с помощью этого инструмента, чтобы проверить, как ваше действие обрабатывает различные способы, которыми пользователь может попросить Ассистента запустить его.
Создать предварительный просмотр
Чтобы протестировать действие приложения с помощью плагина:
- Откройте «Инструменты» > «Google Ассистент» > «Инструмент проверки действий приложения» . Вас могут попросить войти в Android Studio, используя свою учетную запись Google.
- Нажмите «Создать предварительный просмотр» . Если потребуется, просмотрите и примите политику и условия обслуживания App Actions.
Проверьте ожидаемый тип упражнения
Верните виджет, показывающий информацию о последнем завершенном запуске в приложении, выполнив следующие действия в инструменте тестирования:
- На первом этапе, когда инструмент попросит вас выбрать и настроить BII, выберите
actions.intent.GET_EXERCISE_OBSERVATION
. - В поле «Наблюдение за упражнением» измените имя упражнения по умолчанию с
climbing
наrun
. - Нажмите «Запустить действие приложения» .
Протестируйте неожиданный тип упражнения
Чтобы протестировать неожиданный тип упражнения с помощью инструмента тестирования:
- В поле «УпражнениеНаблюдение» обновите значение
name
сRun
наClimbing
. - Нажмите «Запустить действие приложения» .
Ассистент должен вернуть виджет, отображающий информацию «Действия не найдены».
Проверьте резервное намерение
Запросы, запускающие резервное намерение, должны возвращать виджет, отображающий информацию о последней зарегистрированной активности любого типа упражнений.
Чтобы проверить намерение отката:
- В поле «УпражнениеНаблюдение» удалите объект
aboutExercise
. - Нажмите «Запустить действие приложения» .
Ассистент должен вернуть виджет, отображающий информацию о последнем выполненном упражнении.
7. Следующие шаги
Поздравляем!
Теперь у вас есть возможность отвечать на запросы пользователей с помощью виджета Android с помощником.
Что мы рассмотрели
В этой лаборатории вы узнали, как:
- Добавьте виджет приложения в BII.
- Измените виджет, чтобы получить доступ к параметрам из Android Extras.
Что дальше
Отсюда вы можете попробовать внести дополнительные улучшения в свое фитнес-приложение. Чтобы получить ссылку на готовый проект, см. основной репозиторий на GitHub.
Вот несколько советов по дальнейшему изучению расширения этого приложения с помощью действий приложения:
- Посетите справочник по встроенным намерениям App Actions, чтобы узнать больше о способах расширения возможностей ваших приложений для Ассистента.
Чтобы продолжить свое путешествие по Actions on Google, изучите эти ресурсы:
- Developers.google.com/assistant/app : официальный сайт документации по действиям приложения Google Assistant.
- Указатель примеров App Actions : примеры приложений и кода для изучения возможностей App Actions.
- Действия в репозитории Google GitHub : пример кода и библиотек.
- r/GoogleAssistantDev : официальное сообщество Reddit для разработчиков, работающих с Google Assistant.
Следуйте за нами в Твиттере @ActionsOnGoogle, чтобы быть в курсе наших последних объявлений, и пишите в Твиттере #appactions , чтобы поделиться тем, что вы создали!
Опрос обратной связи
Наконец, пожалуйста, заполните этот опрос , чтобы оставить отзыв о своем опыте работы с этой лабораторией кода.