Во многих случаях лучшим ответом является предоставление пользователю простого ответа, краткого подтверждения или быстрого интерактивного взаимодействия. Вы можете отобразить виджет приложения Android в Google Assistant для реализации подобных намерений.
В этом руководстве рассказывается, как выполнять запросы пользователей Ассистента с помощью виджетов и как улучшить работу виджетов для Ассистента с помощью библиотеки расширений виджетов действий приложения.
Преимущества
Виджеты — это миниатюрные представления приложений, которые можно встроить в поверхности Android, например на панель запуска или экран блокировки. С помощью App Actions вы повышаете эффективность своих виджетов, предоставляя им возможность отображаться в Ассистенте:
- Обнаружение: активно отображайте виджеты в ответ на запросы пользователей на естественном языке.
- Вовлеченность: отображайте виджеты в контексте громкой связи, например, когда Ассистент предоставляет персональные результаты на экране блокировки или в Android Auto .
- Сохранение: пользователи могут закреплять виджеты, отображаемые в Ассистенте, на своей панели запуска. Для закрепления функций требуется библиотека расширений виджетов .
Как Ассистент отображает виджеты
Пользователи могут вызывать виджеты в Ассистенте двумя способами:
- Явный запрос виджета по имени.
- Выполнение запроса Ассистенту, который запускает встроенное намерение (BII) или пользовательское намерение , настроенное для выполнения виджета.
Явный вызов
Чтобы явно вызвать виджеты для любого установленного приложения, пользователи могут задавать Ассистенту такие вопросы, как:
- «Окей, Google, покажи виджет exampleApp».
- «Виджеты из exampleApp».
Ассистент отображает эти виджеты с общим описанием: «ExampleApp говорит, вот виджет». Хотя Assistant изначально возвращает виджеты, запрошенные таким образом, без каких-либо действий со стороны разработчика приложения, этот метод вызова требует от пользователя явного знания виджета, чтобы запросить его. Чтобы упростить обнаружение виджетов, используйте метод выполнения намерений, подробно описанный в следующем разделе.
Исполнение намерения
Упростите поиск виджетов, используя их для выполнения запросов на естественном языке, которые пользователи выполняют в Ассистенте. Например, вы можете возвращать виджет всякий раз, когда пользователь запускает GET_EXERCISE_OBSERVATION
BII в вашем фитнес-приложении, спрашивая: «Окей, Google, сколько миль я пробежал на этой неделе в exampleApp?» Помимо упрощения обнаружения, интеграция виджетов с действиями приложений дает следующие преимущества:
- Доступ к параметрам: Ассистент передает параметры намерений , извлеченные из пользовательского запроса, в ваш виджет, обеспечивая возможность персонализированных ответов .
- Пользовательские представления TTS: вы можете предоставить строку преобразования текста в речь (TTS), чтобы Помощник мог объявить при отображении вашего виджета.
- Закрепление виджета: Ассистент отображает кнопку «Добавить этот виджет» рядом с вашим виджетом, позволяя пользователям легко закреплять ваши виджеты на панели запуска.
Реализация виджетов
Чтобы реализовать реализацию виджета в соответствии с вашими намерениями, выполните следующие действия:
- Реализуйте виджет Android, выполнив действия, описанные в разделе Создание простого виджета .
- В файле ресурсов
shortcuts.xml
вашего приложения добавьте элемент<app-widget>
к своей возможности, содержащий сведения о выполнении и теги BII<parameter>
. Обновите свой виджет для обработки параметров. - Добавьте необходимую библиотеку расширений виджетов , которая позволит Ассистенту передавать имена и параметры BII вашим виджетам. Он также позволяет настраивать введение TTS и функцию закрепления виджетов.
В следующем разделе описывается схема <app-widget>
для shortcuts.xml
.
Схема виджета
Элементы <app-widget>
определяются как элементы <capability>
в shortcuts.xml
. Для них требуются следующие атрибуты, если они не указаны как необязательные:
Тег `shortcuts.xml` | Содержится в | Атрибуты |
---|---|---|
<app-widget> | <capability> |
|
<parameter> | <app-widget> |
|
<extra> | <app-widget> |
|
Описание схемы виджета
<приложение-виджет>
Элемент выполнения виджета верхнего уровня.
Атрибуты:
-
android:identifier
: идентификатор для этого выполнения. Это значение должно быть уникальным для элементов выполнения<app-widget>
и<intent>
, определенных в<capability>
. -
android:targetClass
: полное имя классаAppWidgetProvider
для обработки намерения.
<параметр>
Сопоставляет параметр BII со значением <parameter>
намерения. Вы можете определить ноль или более параметров для каждого элемента <app-widget>
. Во время выполнения Ассистент передает параметры, обновляя дополнительные параметры для экземпляра виджета в виде пар ключ-значение в следующем формате:
- Ключ: ключ
android:key
определенный для параметра. - Значение: значение, которое BII извлекает из голосового ввода пользователя.
Доступ к этим дополнительным функциям можно получить, вызвав метод getAppWidgetOptions()
для связанного объекта AppWidgetManager
, который возвращает Bundle
, содержащий имя запускающего BII и его параметры. Подробности см. в разделе Извлечение значений параметров .
Дополнительную информацию о сопоставлении параметров BII см. в разделе Данные параметров и сопоставление .
<дополнительно>
Необязательный тег, объявляющий, что для этого виджета используется собственное введение TTS . Для этого тега требуются следующие значения атрибутов:
-
android:name
:"hasTts"
-
android:value
:"true"
Пример кода
Следующий пример из файла shortcuts.xml
демонстрирует конфигурацию выполнения виджета для возможности GET_EXERCISE_OBSERVATION
BII:
<capability android:name="actions.intent.GET_EXERCISE_OBSERVATION">
<app-widget
android:identifier="GET_EXERCISE_OBSERVATION_1"
android:targetClass="com.exampleapp.providers.exampleAppWidgetProvider"
android:targetPackage="com.exampleapp">
<parameter
android:name="exerciseObservation.aboutExercise.name"
android:key="exercisename">
</parameter>
<extra android:name="hasTts" android:value="true"/>
</app-widget>
</capability>
Вы можете указать несколько элементов <app-widget>
или использовать комбинацию элементов <app-widget>
и <intent>
для каждой возможности. Такой подход позволяет обеспечить индивидуальный подход на основе различных комбинаций параметров, предоставленных пользователями. Например, если пользователь не указывает место высадки в своем запросе, вы можете направить его к действию в вашем приложении, которое показывает варианты настройки мест посадки и высадки. Дополнительные сведения об определении резервных намерений см. в разделе «Намерения отката» .
Извлечение значений параметров
В следующем примере класса AppWidgetProvider
частная функция updateAppWidget()
используется для извлечения имени и параметров BII из параметров виджета Bundle
:
Котлин
package com.example.exampleapp //... Other module imports import com.google.assistant.appactions.widgets.AppActionsWidgetExtension /** * Implementation of App Widget functionality. */ class MyAppWidget : AppWidgetProvider() { override fun onUpdate( context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray ) { // There might be multiple widgets active, so update all of them for (appWidgetId in appWidgetIds) { updateAppWidget(context, appWidgetManager, appWidgetId) } } private fun updateAppWidget( context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int ) { val widgetText: CharSequence = context.getString(R.string.appwidget_text) // Construct the RemoteViews object val views = RemoteViews(context.packageName, R.layout.my_app_widget) views.setTextViewText(R.id.appwidget_text, widgetText) // Extract the name and parameters of the BII from the widget options val optionsBundle = appWidgetManager.getAppWidgetOptions(appWidgetId) val bii = optionsBundle.getString(AppActionsWidgetExtension.EXTRA_APP_ACTIONS_BII) // "actions.intent.CREATE_TAXI_RESERVATION" val params = optionsBundle.getBundle(AppActionsWidgetExtension.EXTRA_APP_ACTIONS_PARAMS) if (params != null && params.containsKey("dropoff")) { val dropoffLocation = params.getString("dropoff") // Build your RemoteViews with the extracted BII parameter // ... } appWidgetManager.updateAppWidget(appWidgetId, views) } }
Ява
package com.example.exampleapp; //... Other module imports import com.google.assistant.appactions.widgets.AppActionsWidgetExtension; /** * Implementation of App Widget functionality. */ public class MyAppWidget extends AppWidgetProvider { @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { // There might be multiple widgets active, so update all of them for (int appWidgetId : appWidgetIds) { updateAppWidget(context, appWidgetManager, appWidgetId); } } private static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { CharSequence widgetText = context.getString(R.string.appwidget_text); // Construct the RemoteViews object RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.my_app_widget); views.setTextViewText(R.id.appwidget_text, widgetText); // Extract the name and parameters of the BII from the widget options Bundle optionsBundle = appWidgetManager.getAppWidgetOptions(appWidgetId); String bii = optionsBundle.getString(AppActionsWidgetExtension.EXTRA_APP_ACTIONS_BII); // "actions.intent.CREATE_TAXI_RESERVATION" Bundle params = optionsBundle.getBundle(AppActionsWidgetExtension.EXTRA_APP_ACTIONS_PARAMS); if (params != null && params.containsKey(("dropoff"))){ String dropoffLocation = params.getString("dropoff"); // Build your RemoteViews with the extracted BII parameter // ... } appWidgetManager.updateAppWidget(appWidgetId, views); } }
Библиотека расширений виджетов
Библиотека расширений виджетов действий приложений расширяет возможности виджетов для голосового помощника. Эта библиотека позволяет вашим виджетам получать важную информацию о выполнении от запускающего BII, включая имя BII и любые параметры намерения, извлеченные из пользовательского запроса.
Эта библиотека Maven позволяет вам предоставлять настраиваемое представление текста в речь (TTS) для каждого виджета, позволяя Assistant объявлять краткое описание контента, визуально отображаемого пользователям. Он также позволяет закреплять панель запуска , что позволяет пользователям легко сохранять виджеты, отображаемые в Ассистенте, на экранах панели запуска.
Начните с добавления библиотеки в раздел зависимостей файла build.gradle
для вашего модуля приложения:
dependencies {
//...
implementation "com.google.assistant.appactions:widgets:0.0.1"
}
Пользовательские представления
После импорта библиотеки расширений виджетов вы можете предоставить собственные представления TTS для своих виджетов. Чтобы добавить свое определение в AppWidgetProvider
виджета, откройте класс в своей IDE и импортируйте библиотеку расширений виджетов:
Котлин
import com.google.assistant.appactions.widgets.AppActionsWidgetExtension
Ява
import com.google.assistant.appactions.widgets.AppActionsWidgetExtension;
Котлин
package com.example.exampleapp //... Other module imports import com.google.assistant.appactions.widgets.AppActionsWidgetExtension /** * Implementation of App Widget functionality. */ object MyAppWidget : AppWidgetProvider() { fun updateAppWidget( context: Context?, appWidgetManager: AppWidgetManager, appWidgetId: Int ) { val appActionsWidgetExtension = AppActionsWidgetExtension.newBuilder(appWidgetManager) .setResponseSpeech("Hello world") // TTS to be played back to the user .setResponseText("Hello world!") // Response text to be displayed in Assistant .build() // Update widget with TTS appActionsWidgetExtension.updateWidget(appWidgetId) // Update widget UI appWidgetManager.updateAppWidget(appWidgetId, views) } }
Ява
package com.example.exampleapp; //... Other module imports import com.google.assistant.appactions.widgets.AppActionsWidgetExtension; /** * Implementation of App Widget functionality. */ public class MyAppWidget extends AppWidgetProvider { static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { AppActionsWidgetExtension appActionsWidgetExtension = AppActionsWidgetExtension.newBuilder(appWidgetManager) .setResponseSpeech("Hello world") // TTS to be played back to the user .setResponseText("Hello world!") // Response text to be displayed in Assistant .build(); // Update widget with TTS appActionsWidgetExtension.updateWidget(appWidgetId); // Update widget UI appWidgetManager.updateAppWidget(appWidgetId, views); } }
Рекомендации по стилю TTS
Используйте следующие рекомендации по стилю, чтобы оптимизировать представление пользовательских виджетов для TTS и отображаемых подсказок.
Рекомендация | Рекомендуется | Не рекомендуется |
---|---|---|
СхваткиИспользуйте сокращения в подсказках TTS. Сообщения без сокращений звучат неестественно и роботизированно, а не естественно и разговорно. Такие слова, как «нельзя» и «нельзя», могут звучать как наказание и резкость. | ResponseSpeech (TTS)Извините, я не могу найти бронирование. ResponseText Извините, я не могу найти бронирование. | ResponseSpeech (TTS)Извините, я не могу найти бронирование. ResponseText Извините, я не могу найти бронирование. |
ЗапятыеДобавьте ясности, используя запятые в списках из трех и более элементов. Без порядковой запятой отдельные элементы в вашем списке могут быть неправильно восприняты или прочитаны как группы. Например, в слове «Нарциссы, ромашки и подсолнухи» слова «ромашки и подсолнухи» звучат так, будто они собираются вместе. В «нарциссах, маргаритках и подсолнухах» все три явно разделены. | ResponseSpeech (TTS)Среди наших самых популярных — желтые розы, нарциссы, ромашки и подсолнухи. ResponseText Среди наших самых популярных — желтые розы, нарциссы, ромашки и подсолнухи. | ResponseSpeech (TTS)Среди наших самых популярных — желтые розы, нарциссы, ромашки и подсолнухи. ResponseText Среди наших самых популярных — желтые розы, нарциссы, ромашки и подсолнухи. |
ЦифрыИспользуйте цифры вместо текста, чтобы сделать визуальный контент более понятным. | ResponseSpeech (TTS)Ваше кровяное давление 100 на 80. ResponseText Ваше кровяное давление 100/80. | ResponseSpeech (TTS)Ваше кровяное давление 100/80. ResponseText Ваше кровяное давление сто выше восьмидесяти. |
СимволыИспользуйте специальные символы вместо текста, чтобы сделать визуальный контент более понятным. | ResponseSpeech (TTS)Ваша последняя покупка стоила 24,65 доллара США. ResponseText Ваша последняя покупка стоила 24,65 доллара США. | ResponseSpeech (TTS)Ваша последняя покупка стоила двадцать четыре доллара шестьдесят пять центов. ResponseText Ваша последняя покупка стоила двадцать четыре доллара шестьдесят пять центов. |
Избегайте тонкостейИзящества делают ответы отстраненными и формальными. Откажитесь от них и ведите разговор дружелюбно и неформально. | ResponseSpeech (TTS)Ваш заказ доставлен. ResponseText Ваш заказ доставлен. | ResponseSpeech (TTS)Конечно, я могу вам это сказать. Ваш заказ доставлен. ResponseText Конечно, я могу вам это сказать. Ваш заказ доставлен. |
Избегайте восклицательных знаковИх можно воспринимать как крик. | ResponseSpeech (TTS)Сегодня ты пробежал 1,5 мили. ResponseText Сегодня ты пробежал 1,5 мили. | ResponseSpeech (TTS)Сегодня ты пробежал 1,5 мили! ResponseText Сегодня ты пробежал 1,5 мили! |
ВремяИспользуйте цифры: «5:15» вместо «пять пятнадцать» или «четверть пятого». Для 12-часового формата времени используйте AM или PM. | ResponseSpeech (TTS)Ваша доставка должна прибыть к 8:15 утра. ResponseText Ваша доставка должна прибыть к 8:15 утра. | ResponseSpeech (TTS)Ваша доставка должна прибыть сегодня к 15 минутам десятого утра. ResponseText Ваша доставка должна прибыть сегодня к 15 минутам десятого утра. |
Не впадайте в монологиБудьте информативны, но ответы должны быть краткими. Не вдавайтесь в сложные детали без явной выгоды для пользователя. | ResponseSpeech (TTS)В прошлом месяце вы израсходовали 159 часов энергии. ResponseText В прошлом месяце вы израсходовали 159 часов энергии. | ResponseSpeech (TTS)Экономия энергии очень важна для планеты и окружающей среды. В прошлом месяце вы израсходовали 159 часов энергии. За этот месяц вы израсходовали 58 часов энергии. ResponseText Экономия энергии очень важна для планеты и окружающей среды. В прошлом месяце вы израсходовали 159 часов энергии. За этот месяц вы израсходовали 58 часов энергии. |
Используйте короткие и простые словаПростой и понятный язык имеет самую широкую привлекательность, что делает его доступным для людей любого происхождения. | ResponseSpeech (TTS)Ваше последнее измерение уровня сахара в крови было 126. ResponseText Последнее измерение уровня сахара в крови составило 126 мг/дл. | ResponseSpeech (TTS)Предпоследний уровень глюкозы в крови был 126. ResponseText Предпоследний уровень глюкозы в крови был 126. |
Закрепление лаунчера
Библиотека расширений виджетов позволяет отображать кнопку «Добавить этот виджет» вместе с вашим виджетом в Ассистенте. Чтобы включить закрепление, добавьте следующее определение получателя в AndroidManifest.xml
:
<application>
<receiver android:name="com.google.assistant.appactions.widgets.pinappwidget.PinAppWidgetBroadcastReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.google.assistant.appactions.widgets.COMPLETE_PIN_APP_WIDGET" />
</intent-filter>
</receiver>
<service
android:name=
"com.google.assistant.appactions.widgets.pinappwidget.PinAppWidgetService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action
android:name="com.google.assistant.appactions.widgets.PIN_APP_WIDGET" />
</intent-filter>
</service>
</application>
Доступность инвентаря
BII, поддерживающие встроенную инвентаризацию или веб-инвентаризацию, могут расширить эти инвентаризации для выполнения ваших виджетов.
Встроенный инвентарь
Следующий код из примера файла shortcuts.xml
демонстрирует возможность START_EXERCISE
BII, настроенную для встроенной инвентаризации и выполнения виджетов:
<capability
android:name="actions.intent.START_EXERCISE">
<app-widget
android:identifier="START_EXERCISE_1"
android:targetClass="com.example.exampleapp.StartExerciseAppWidgetProvider">
<parameter
android:name="exercise.name"
android:key="exerciseName"
app:shortcutMatchRequired="true">
</parameter>
</app-widget>
</capability>
<shortcut android:shortcutId="RunningShortcut">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.example.exampleapp.StartExcerciseActivity" />
<capability-binding
android:capability="actions.intent.START_EXERCISE"
android:parameter="exercise.name"
android:value="running;runs" />
</shortcut>
В предыдущем примере, когда пользователь запускает эту возможность, спрашивая Ассистента: «Начните работу с примером приложения», пакет опций для выполнения <app-widget>
содержит следующую пару ключ-значение:
- Ключ =
“exerciseName”
- Значение =
“RunningShortcut”
Веб-инвентаризация
Следующий код из примера файла shortcuts.xml
демонстрирует возможность веб-инвентаризации и выполнения виджетов:
<shortcuts>
<capability
android:name="actions.intent.START_EXERCISE">
<app-widget
android:identifier="START_EXERCISE_1"
android:targetClass="com.example.exampleapp.CreateTaxiAppWidgetProvider">
<parameter
android:name="exercise.name"
android:key="exerciseName"
android:mimeType="text/*">
<data android:pathPattern="https://exampleapp.com/exercise/.*" />
</parameter>
</app-widget>
</capability>
</shortcuts>
Действия тестового приложения
Используйте инструмент тестирования действий приложения — функцию плагина Google Assistant для Android Studio — для тестирования виджетов на физическом или виртуальном устройстве. Чтобы использовать инструмент тестирования, выполните следующие действия:
- Подключите тестовое устройство с работающим приложением.
- В Android Studio выберите «Инструменты» > «Действия приложения» > «Инструмент проверки действий приложения» .
- Нажмите Создать предварительный просмотр .
- Используя Android Studio, запустите приложение на тестовом устройстве.
- Используйте приложение «Ассистент» на тестовом устройстве, чтобы протестировать действие приложения. Например, вы можете сказать что-то вроде : «Окей, Google, сколько миль я пробежал на этой неделе с помощью приложения exampleApp?»
- Наблюдайте за поведением своего приложения или используйте отладчик Android Studio , чтобы проверить желаемый результат действия.
Рекомендации по качеству
В этом разделе освещаются основные требования и рекомендации по интеграции действий приложения с виджетами.
Контент в виджетах
- ( Обязательно ) Не показывать рекламу в виджетах.
- Сосредоточьте содержимое виджета полностью на достижении цели. Не пытайтесь реализовать несколько целей с помощью одного виджета или добавлять нерелевантный контент.
Обработка аутентификации
- ( Обязательно ) Если для завершения пользовательского потока необходима аутентификация пользователя, верните виджет, объясняющий, что пользователю необходимо продолжить работу в приложении. Встроенная аутентификация пользователя в Google Assistant не поддерживается для действий приложения.
- Если пользователи разрешают вашему приложению отображать данные с помощью виджетов, вы можете вернуть виджет ошибки во время выполнения для неавторизованных пользователей.
Резервные намерения
( Обязательно ) В файле
shortcuts.xml
всегда указывайте резервный<intent>
в дополнение к выполнению виджета для заданной возможности. Резервное намерение — это элемент<intent>
без обязательных значений<parameter>
.Это позволяет Ассистенту выполнять действие, когда пользовательский запрос не содержит параметров, требуемых другими элементами выполнения, определенными в этой возможности. Исключением является случай, когда для этой возможности нет обязательных параметров, и в этом случае требуется только выполнение виджета.
Используйте резервное намерение, чтобы открыть приложение на соответствующем экране, а не на главном экране.
Следующий код из примера файла shortcuts.xml
демонстрирует <capability>
с резервным <intent>
, поддерживающим основное выполнение <app-widget>
:
<shortcuts>
<capability
android:name="actions.intent.CREATE_TAXI_RESERVATION">
<!-- Widget with required parameter, specified using the "android:required" attribute. -->
<app-widget
android:identifier="CREATE_TAXI_RESERVATION_1"
android:targetClass="com.example.myapplication.CreateTaxiAppWidgetProvider">
<parameter
android:name="taxiReservation.dropoffLocation.name"
android:key="dropoff"
android:required="true">
</parameter>
</app-widget>
<!-- Fallback intent with no parameters required to successfully execute. -->
<intent
android:identifier="CREATE_TAXI_RESERVATION_3"
android:action="myapplication.intent.CREATE_TAXI_RESERVATION_1"
android:targetClass="com.example.myapplication.TaxiReservationActivity">
</intent>
</capability>
</shortcuts>
Раскрытие данных Google Play
В этом разделе перечислены данные конечных пользователей, собранные последней версией библиотеки расширений виджетов.
Этот SDK отправляет предоставленные разработчиком ответы преобразования текста в речь (TTS), которые объявляются пользователю Google Assistant с использованием речевой технологии Assistant. Эта информация не хранится в Google.
Действия приложения также могут собирать метаданные клиентского приложения для следующих целей:
- Для мониторинга темпов внедрения различных версий SDK.
- Для количественной оценки использования функций SDK в приложениях.
Контент и образцы кода на этой странице предоставлены по лицензиям. Java и OpenJDK – это зарегистрированные товарные знаки корпорации Oracle и ее аффилированных лиц.
Последнее обновление: 2024-10-26 UTC.