Чтобы сценарий смартапа понимал, что происходит в клиентской части у пользователя, ему нужно получать текущее состояние смартапа, например, статус воспроизведения звуковой дорожки или состояние игрового персонажа. Данные о состоянии передаются в сценарий вместе с каждой голосовой командой пользователя.
Состояние после запроса пользователя
При получении реплики пользователя, система вызывает метод get_state()
, который проверяет хранилище appStateHolder
и дописывает его содержимое в запрос ассистента, который передается в сценарий.
Состояние передается в запросе MESSAGE_TO_SKILL
, в поле payload.meta.current_app.state.<имя_состояния_из_системного_хранилища>
.
Для передачи состояния фронтенда смартапа в бэкенд используются следующие объекты библиотеки Appstate
:
appState
– это объект, содержащий информацию о текущем состоянии приложения.appState
может содержать любые сериализуемые поля.appStateHolder
– системное хранилище для объектаappState
. Может содержать только одно состояние смартапа. Фронтенд может в любой момент обновить системное хранилище с помощью методаsetState()
, который возвращает объектappState
.appStateProvider
– предоставляет ОС устройства доступ к состоянию приложения в момент обращения пользователя. Для получения состояния ОС использует методgetState()
, который возвращает объектappState
. Вы можете использовать этот интерфейс, например, чтобы поддержать голосовое управление плеером.Объект
appState
обрабатывается, только когда приложение запущено на экране пользователя.
Примеры состояний:
appStateHolder.setState(
Json.encodeToString(
MyCurrentScreenAppState(currentScreen = Screen.Main) // отображается главный экран смартапа
)
)
appStateHolder.setState(
Json.encodeToString(
MyHealthAppState(health = 53) // уровень здоровья персонажа — 53
)
)
appStateHolder.setState(
Json.encodeToString(
MyAppState("На андроиде ${currentClothes.joinToString(transform = { it.clothes })}") // на андроиде надета шапка
)
)
Обмен данными в неголосовых запросах
В Native App Android-приложение (фронтенд) и сценарий (бэкенд) могут обмениваться данными в фоне или при действиях пользователя, например, при нажатии кнопок интерфейса. Чтобы настроить обмен данными, подключите библиотеку Messaging (входит в состав Native-App SDK).
Данные передаются в запросе SERVER_ACTION
, который содержит объект server_action
с произвольным идентификатором и параметрами сообщения.
Кроме SERVER_ACTION
вы можете отправить запросы, описанные в классе MessageName
. Примеры и описания запросов можно посмотреть в справке SmartApp API.
Класс содержит запросы, не описанные в SmartApp API. Они используются внутренними приложениями в служебных целях.
Отправка данных
Для создания запроса SERVER_ACTION
в демонстрационном Native App используется класс ServerAction
:
@Serializable
internal data class ServerAction<T>(
@SerialName("action_id")
val actionId: String,
@SerialName("parameters")
val parameters: T
)
Созданный запрос нужно передать в методе sendAction()
вместе с названием запроса, например так:
private fun formActionFromNativeApp(): Payload =
Payload(
json.encodeToString(
ServerAction(
actionId = "ACTION_FROM_NATIVE_APP"
)
)
)
viewModelScope.launch(ioCoroutineDispatcher) {
messaging.sendAction(
MessageName.SERVER_ACTION,
formActionFromNativeApp()
)
}
Получение данных в сценарии
После вызова метода sendAction()
ассистент передает сообщение в сценарий Native App.
Для получения запроса в сценарии используется тег event!
, в котором нужно указать идентификатор сообщения из поля action_id
:
state: ActionNativeApp
event!: ACTION_FROM_NATIVE_APP
После чего запрос можно будет обработать необходимым образом.