Интегрируйте виджеты Android с Google Assistant

1. Обзор

В первом практическом занятии по App Actions вы узнали, как расширить функциональность Google Assistant для примера фитнес-приложения, реализовав встроенные интенты (BII) из категории BII «Здоровье и фитнес».

Функция App Actions позволяет пользователям запускать определенные функции приложений непосредственно из Ассистента, задавая, например: « Привет, Google, начни пробежку в ExampleApp». Помимо запуска приложений, Ассистент может отображать пользователю интерактивный виджет Android для выполнения запросов для соответствующих BII-функций.

На экране отображается, как Ассистент возвращает виджет в ответ на запрос пользователя, который активировал возможность BII GET_EXERCISE_OBSERVATION приложения.

Что вы построите

В этом практическом занятии вы научитесь возвращать виджеты Android для выполнения запросов пользователей Google Ассистента. Вы также узнаете:

  • Используйте параметры BII для персонализации виджетов.
  • Добавьте в Assistant голосовые вступительные фразы, воспроизводимые с помощью функции преобразования текста в речь (TTS).
  • Используйте справочник встроенных намерений , чтобы определить, какие встроенные намерения поддерживают выполнение виджетов.

Предварительные требования

Прежде чем продолжить, убедитесь, что ваша среда разработки готова для использования App Actions. Она должна включать в себя:

  • Терминал для выполнения команд оболочки с установленным Git.
  • Последняя стабильная версия Android Studio .
  • Физическое или виртуальное устройство Android с доступом в Интернет.
  • Учетная запись Google, которая авторизована в Android Studio, приложении Google и приложении Google Assistant.

Если вы используете физическое устройство, подключите его к локальному компьютеру разработчика.

2. Разберитесь, как это работает.

Google Ассистент использует понимание естественного языка (NLU) для чтения запроса пользователя и сопоставления его со встроенным намерением Ассистента (BII). Затем Ассистент сопоставляет намерение с возможностью (реализующей BII), которую вы регистрируете для этого намерения в своем приложении. Наконец, Ассистент выполняет запрос пользователя, отображая виджет Android, сгенерированный вашим приложением на основе данных, найденных в этой возможности.

В этом практическом задании вы определяете возможность, которая регистрирует поддержку BII GET_EXERCISE_OBSERVATION . В этой возможности вы указываете Ассистенту сгенерировать Android-интент для класса виджета FitActions , чтобы выполнить запросы для этого BII. Вы обновляете этот класс, чтобы сгенерировать персонализированный виджет для отображения Ассистентом пользователю, а также текстовое сопровождение для озвучивания Ассистентом.

Следующая диаграмма иллюстрирует этот процесс:

Блок-схема, демонстрирующая выполнение действий виджетом Assistant.

Виджет FitActions

В демонстрационном приложении FitActions содержится виджет с информацией о тренировке, который пользователи могут добавить на главный экран. Этот виджет отлично подходит для обработки запросов пользователей, запускающих BII-функцию GET_EXERCISE_OBSERVATION .

Как работает виджет

Когда пользователь добавляет виджет на главный экран, виджет отправляет запрос широковещательному приемнику устройства. Этот сервис получает информацию о виджете из определения приемника виджета в ресурсе 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. Эти изменения включают в себя:

  1. Настройка возможности BII GET_EXERCISE_OBSERVATION для возврата экземпляра объекта StatsWidget .
  2. Обновление класса StatsWidget для использования функций App Actions, таких как:
    • Использование параметров BII позволяет пользователям просматривать статистику конкретных тренировок, задавая вопросы, например: «Привет, Google, покажи мне статистику моих пробежек в ExampleApp».
    • Предоставление вводных строк для синтеза речи.
    • Обработка особых случаев, например, когда пользовательский запрос не содержит параметра типа тренировки.

3. Подготовьте среду разработки.

Загрузите базовые файлы.

Выполните эту команду, чтобы клонировать репозиторий GitHub с примером приложения:

git clone --branch start-widget-codelab https://github.com/actions-on-google/appactions-fitness-kotlin.git

После клонирования репозитория выполните следующие действия, чтобы открыть его в Android Studio:

  1. В диалоговом окне «Добро пожаловать в Android Studio» нажмите «Импорт проекта» .
  2. Найдите и выберите папку, куда вы клонировали репозиторий.

Чтобы увидеть версию приложения, соответствующую пройденному практическому заданию, клонируйте репозиторий с примерами приложений, используя флаг --branch master .

Обновите идентификатор приложения Android.

Обновление идентификатора приложения позволяет однозначно идентифицировать приложение на вашем тестовом устройстве и избежать ошибки «Дублирующееся имя пакета», если приложение загружено в Play Console. Чтобы обновить идентификатор приложения, откройте файл app/build.gradle :

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

Замените "MYUNIQUENAME" в поле applicationId на уникальное для вас имя.

Установите тестовый плагин

Плагин Google Assistant позволяет тестировать действия вашего приложения на тестовом устройстве. Он работает, отправляя информацию в Assistant через приложение Google на вашем устройстве Android. Если у вас еще нет плагина, установите его, выполнив следующие действия:

  1. Перейдите в меню Файл > Настройки ( в Android Studio > Настройки на MacOS).
  2. В разделе «Плагины» перейдите в Marketplace и найдите «Google Assistant». Вы также можете вручную загрузить и установить тестовый инструмент.
  3. Установите инструмент и перезапустите Android Studio.

Протестируйте приложение на своем устройстве.

Прежде чем вносить дальнейшие изменения в приложение, полезно ознакомиться с возможностями демонстрационного примера.

Запустите приложение на тестовом устройстве:

  1. В Android Studio выберите ваше физическое или виртуальное устройство и выберите Run > Run app или нажмите Run. Запустите значок приложения в Android Studio. на панели инструментов.
  2. Нажмите и удерживайте кнопку «Домой», чтобы настроить Ассистента и убедиться в его работоспособности. Вам потребуется войти в Ассистента на вашем устройстве, если вы еще этого не сделали.

Для получения дополнительной информации о виртуальных устройствах Android см. раздел «Создание и управление виртуальными устройствами» .

Кратко изучите приложение, чтобы увидеть, на что оно способно. Приложение автоматически заполняет 10 вариантов упражнений и отображает эту информацию при первом запуске.

Попробуйте существующий виджет.

  1. Нажмите кнопку «Домой» , чтобы перейти на главный экран вашего тестового устройства.
  2. Нажмите и удерживайте пустое место на главном экране и выберите «Виджеты» .
  3. Прокрутите список виджетов вниз до раздела FitActions .
  4. Нажмите и удерживайте значок FitActions, чтобы разместить его виджет на главном экране.

Скриншот, демонстрирующий виджет FitActions на главном экране устройства.

4. Добавьте действие приложения.

На этом шаге вы добавляете возможность BII GET_EXERCISE_OBSERVATION . Для этого добавьте новый элемент capability в shortcuts.xml . Эта возможность определяет, как запускается данная функция, как используются параметры BII и какие Android-интенты следует вызвать для выполнения запроса.

  1. Добавьте новый элемент capability в ресурс shortcuts.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 .

Эта возможность сопоставляет BII-объект GET_EXERCISE_OBSERVATION с намерением app-widget , так что при срабатывании BII-объекта виджет создается и отображается пользователю.

Перед запуском виджета Ассистент извлекает поддерживаемые параметры BII из запроса пользователя. Для этого практического занятия требуется параметр BII exerciseObservation.aboutExercise.name , который представляет собой запрошенный пользователем тип упражнения. Приложение поддерживает три типа упражнений: «бег», «ходьба» и «езда на велосипеде». Вы предоставляете встроенный список , чтобы сообщить Ассистенту о поддерживаемых значениях.

  1. Определите эти элементы инвентаризации, добавив следующую конфигурацию в shortcuts.xml , выше параметра GET_EXERCISE_OBSERVATION :
    <!-- 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" . В таких ситуациях Ассистент требует от вас определить резервное намерение, позволяющее выполнить запрос успешно, даже если в запросе не указаны параметры.

  1. В 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 обновите класс виджета, чтобы он поддерживал голосовой вызов действий приложения.

Добавьте библиотеку расширений виджетов.

Библиотека расширений App Actions Widgets Extension расширяет возможности ваших виджетов для работы с голосовым помощником. В частности, она позволяет задавать пользовательское вступление в формате TTS для ваших виджетов.

  1. Добавьте зависимость библиотеки Widgets Extension в ресурс /app/build.gradle примера приложения:
    // app/build.gradle
    
    dependencies {
      //...
      implementation "com.google.assistant.appactions:widgets:0.0.1"
    }
    
    В появившемся в Android Studio окне предупреждения нажмите «Синхронизировать сейчас» . Синхронизация после каждого изменения build.gradle помогает избежать ошибок при сборке приложения.

Добавить сервис виджетов

Сервис — это компонент приложения, способный выполнять длительные операции в фоновом режиме. Вашему приложению необходимо предоставлять сервис для обработки запросов виджетов.

  1. Добавьте службу в ресурс 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 , который отображается в Ассистенте.

Обновите класс виджета

Теперь ваше приложение настроено на переадресацию запросов GET_EXERCISE_OBSERVATION в ваш класс виджета. Далее обновите класс StatsWidget.kt , чтобы создать экземпляр виджета, персонализированный под запрос пользователя, используя значения параметров BII.

  1. Откройте класс StatsWidget.kt и импортируйте библиотеку расширения App Actions Widget Extension:
    // StatsWidget.kt
    
    // ... Other import statements
    import com.google.assistant.appactions.widgets.AppActionsWidgetExtension
    
    
  2. Добавьте следующие приватные переменные, которые вы используете при определении информации, которая должна заполнять виджет:
    // StatsWidget.kt
    
    private val hasBii: Boolean
    private val isFallbackIntent: Boolean
    private val aboutExerciseName: String
    private val exerciseType: FitActivity.Type
    
  3. Добавьте функцию init , чтобы класс мог использовать данные параметров виджета, переданные из Assistant:
    // 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
    • Объекты Bundle предназначены для использования на разных этапах процесса, между действиями с намерениями, а также для хранения временного состояния при изменении конфигурации. Assistant использует объекты Bundle для передачи данных конфигурации виджету.
  • bii = actions.intent.GET_EXERCISE_OBSERVATION
    • Название BII можно получить из пакета, используя расширение AppActionsWidgetExtension .
  • hasBii = true
    • Проверяет наличие BII.
  • params = Bundle[{aboutExerciseName=running}]
    • Специальный пакет (Bundle), генерируемый действиями приложения (App Actions), вложен в Bundle параметров виджета (Visitd options Bundle). Он содержит пары ключ/значение BII. В данном случае значение running было извлечено из примера запроса: "Hey Google, show my running stats on ExampleApp".
  • isFallbackIntent = false
    • Проверяет наличие необходимых параметров BII в параметрах Extras .
  • aboutExerciseName = running
    • Получает значение параметра Extras для aboutExerciseName .
  • exerciseType = RUNNING
    • Использует aboutExerciseName для поиска соответствующего объекта типа в базе данных.

Теперь, когда класс StatsWidget может обрабатывать входящие данные из Android-интентов App Actions, обновите логику создания виджета, чтобы проверять, был ли виджет запущен действием App Action.

  1. В 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 , передаваемые из Android-интента App Actions.

  1. Добавьте функцию 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), которую Ассистент будет озвучивать при отображении вашего виджета. Мы рекомендуем включить её, чтобы обеспечить звуковой контекст для ваших виджетов. Эта функция предоставляется библиотекой расширений App Actions Widgets Extension, которая позволяет устанавливать текст и TTS-вступления, сопровождающие ваши виджеты в Ассистенте.

Удачное место для введения в технологию преобразования текста в речь — это функция formatDataAndSetWidget , которая форматирует данные об активности, возвращаемые из базы данных приложения.

  1. В 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 экземпляру виджета.

  1. Добавьте новую функцию 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)
    }
    

Наконец, завершите логику преобразования текста в речь, установив информацию о преобразовании текста в речь, когда база данных упражнений возвращает пустые данные для запрошенного типа тренировки.

  1. Обновите функцию 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 на тестовом устройстве. С помощью этого инструмента вы можете настроить параметры намерения для действия приложения, чтобы проверить, как ваше действие обрабатывает различные способы, которыми пользователь может попросить Assistant его выполнить.

Создать предварительный просмотр

Чтобы протестировать действие вашего приложения с помощью плагина:

  1. Перейдите в меню Инструменты > Google Ассистент > Инструмент тестирования действий приложения . Возможно, вам потребуется войти в Android Studio, используя свою учетную запись Google.
  2. Нажмите «Создать предварительный просмотр» . При необходимости ознакомьтесь с политикой и условиями использования App Actions и примите их.

Проверьте ожидаемый тип упражнений.

В инструменте тестирования выполните следующие действия, чтобы получить виджет, отображающий информацию о последнем завершенном запуске приложения:

  1. На первом шаге, когда инструмент запрашивает выбор и настройку BII, выберите actions.intent.GET_EXERCISE_OBSERVATION .
  2. В поле exerciseObservation измените название упражнения по умолчанию с climbing на run .
  3. Нажмите «Запустить действие приложения» .

Экран, отображающий виджет, полученный с помощью плагина Google Ассистента.

Попробуйте неожиданный вид упражнений.

Чтобы проверить неожиданный тип упражнений в инструменте тестирования:

  1. В поле exerciseObservation измените значение name с Run на Climbing .
  2. Нажмите «Запустить действие приложения» .

Ассистент должен вернуть виджет с информацией "Активность не найдена".

При использовании плагина Google Ассистента отобразился экран с виджетом, на котором отсутствовала информация о физических упражнениях.

Проверьте резервный вариант намерения

Запросы, запускающие резервный вариант, должны возвращать виджет, отображающий информацию о последней зарегистрированной активности любого типа упражнений.

Чтобы проверить резервный вариант:

  1. В поле exerciseObservation удалите объект aboutExercise .
  2. Нажмите «Запустить действие приложения» .

Функция «Помощник» должна вернуть виджет, отображающий информацию о последнем завершенном упражнении.

На экране отображается виджет с последней записанной активностью, созданный с помощью плагина Google Assistant.

7. Дальнейшие шаги

Поздравляем!

Теперь у вас есть возможность отвечать на запросы пользователей с помощью виджета Android с функцией Assistant.

Что мы рассмотрели

В этом практическом занятии вы научились:

  • Добавить виджет приложения в BII.
  • Измените виджет для доступа к параметрам из Android Extras.

Что дальше?

Отсюда вы можете попробовать внести дальнейшие улучшения в свое фитнес-приложение. Чтобы посмотреть готовый проект, перейдите в основной репозиторий на GitHub.

Вот несколько рекомендаций для дальнейшего изучения возможностей расширения функциональности этого приложения с помощью App Actions:

Чтобы продолжить работу с Actions on Google, ознакомьтесь с этими ресурсами:

Подписывайтесь на нас в Твиттере @ActionsOnGoogle , чтобы быть в курсе наших последних объявлений, и делитесь своими разработками в Твиттере с хэштегом #appactions !

Опрос обратной связи

В заключение, пожалуйста, заполните этот опрос , чтобы оставить отзыв о вашем опыте работы с этим практическим занятием.