1. Прежде чем начать
API Google Home предоставляют разработчикам Android набор библиотек для использования экосистемы Google Home. С помощью этих новых API разработчики могут создавать приложения для удобного подключения и управления устройствами умного дома.
Google предоставляет пример приложения для Android для разработчиков, желающих получить доступ к рабочему примеру с использованием API Google Home. Эта лабораторная работа основана на ветке примера приложения, которая покажет, как использовать API Permissions, Commissioning, Device и Structure.
Предпосылки
- Знание экосистемы Google Home ( Cloud-to-cloud и Matter ).
- Рабочая станция с установленной Android Studio (2024.3.1 Ladybug или более поздняя версия).
- Телефон Android, соответствующий требованиям Home API (см. Предварительные требования ) с установленными сервисами Google Play и приложением Google Home .
- Совместимый Google Home Hub , поддерживающий API Google Home .
- Дополнительно — устройство «умного дома», совместимое с API Google Home.
Чему вы научитесь
- Как создать приложение для Android с использованием API Google Home и передового опыта.
- Как использовать API устройств и структур для представления и управления умным домом.
- Как использовать Commissioning API для добавления устройств в экосистему Google Home.
Дополнительно: обустройте свой дом
Перед использованием API Google Home вам необходимо настроить дом в своей учётной записи Google с помощью приложения Google Home и добавить несколько устройств. В этом разделе описывается, как это сделать с помощью Google Home Playground , предоставляющего виртуальные устройства для умного дома.
Откройте home-playground.withgoogle.com в своем веб-браузере, войдите в свою учетную запись Google и проверьте, отображаются ли следующие эмулируемые устройства:
- розетка 1: вилка вкл/выкл
- light2: Регулируемый свет
- light3: включение/выключение света
- ac3: Кондиционер
- blinds4: Оконные покрытия
- washer5: Умная стиральная машина
Откройте приложение Google Home на мобильном устройстве, нажмите кнопку «Добавить » и выберите «Работает с Google Home». Найдите в списке «игровая площадка», затем выберите проект «Google Home Playground» и нажмите « Продолжить» .
В Google Home Playground откроется страница авторизации учётной записи. Нажмите «Авторизовать» или «Войти через Google» . В мобильном приложении вы увидите все устройства, настроенные вами в веб-приложении.
Выберите все устройства и завершите процесс настройки. Вернувшись на главную страницу, вы увидите все доступные устройства.
Поддерживаемые устройства из списка теперь доступны для использования с API Google Home.
2. Настройте свой проект
На следующей диаграмме показана архитектура приложения Home API:
- Код приложения: основной код, над которым работают разработчики для создания пользовательского интерфейса приложения и логики взаимодействия с Home API SDK.
- Home API SDK: Home API SDK, предоставляемый Google, работает со службой Home API в GMSCore для управления устройствами умного дома. Разработчики создают приложения, работающие с Home API, объединяя их с Home API SDK.
- GMSCore на Android: GMSCore, также известный как сервисы Google Play, — это платформа Google, предоставляющая основные системные сервисы, обеспечивающие ключевые функции на всех сертифицированных устройствах Android. Модуль Home сервисов Google Play содержит сервисы, взаимодействующие с API Home.
Настройте Home SDK
Чтобы получить последнюю версию SDK, следуйте инструкциям в разделе Настройка SDK .
Получить образец приложения
Исходный код приложения-примера доступен на GitHub. В этой лабораторной работе используются примеры из ветки codelab-branch-1
приложения-примера.
Перейдите туда, где вы хотите сохранить проект, и клонируйте ветку codelab-branch-1
:
$ git clone -b codelab-branch-1 https://github.com/google-home/google-home-api-sample-app-android.git
Создайте пример приложения
Выполните шаги 1–5 из раздела «Создание приложения» .
После успешного запуска приложения на вашем телефоне вы увидите главную страницу приложения Sample App. Но вы не сможете войти в систему, пока не настроите аутентификацию OAuth и не реализуете недостающие элементы с помощью API Permission.
3. Настройте аутентификацию
API Home используют OAuth 2.0 для предоставления доступа к устройствам в структуре. OAuth позволяет пользователю предоставлять разрешение приложению или службе, не раскрывая свои учётные данные.
Следуйте инструкциям в разделе «Настройка согласия OAuth» , чтобы настроить экран согласия. Обязательно создайте хотя бы одну тестовую учётную запись.
Затем следуйте инструкциям в разделе Настройка учетных данных OAuth , чтобы создать учетные данные для приложения.
4. Инициализация и обработка разрешений
В этом разделе вы узнаете, как инициализировать SDK и обрабатывать разрешения пользователей, заполнив недостающие части с помощью API разрешений.
Определить поддерживаемые типы и характеристики
При разработке приложения необходимо явно указать, какие типы устройств и характеристики оно будет поддерживать. В примере приложения мы делаем это, определяя статические списки в объекте-компаньоне в HomeApp.kt
, на которые затем можно ссылаться по мере необходимости в приложении:
companion object {
// List of supported device types by this app:
val supportedTypes: List<DeviceTypeFactory<out DeviceType>> = listOf(
OnOffLightDevice,
DimmableLightDevice,
// ...
)
// List of supported device traits by this app:
val supportedTraits: List<TraitFactory<out Trait>> = listOf(
OnOff,
LevelControl,
// ...
)
}
Ознакомьтесь с разделами Поддерживаемые типы устройств и Индекс характеристик на Android, чтобы узнать обо всех поддерживаемых типах устройств и характеристиках.
Раскомментируйте шаги 4.1.1 и 4.1.2 в исходном файле HomeApp.kt
, чтобы включить исходный код, запрашивающий разрешение.
companion object {
// List of supported device types by this app:
val supportedTypes: List<DeviceTypeFactory<out DeviceType>> = listOf(
// TODO: 4.1.1 - Non-registered device types will be unsupported
// ContactSensorDevice,
// ColorTemperatureLightDevice,
// DimmableLightDevice,
// ExtendedColorLightDevice,
// GenericSwitchDevice,
// GoogleDisplayDevice,
// GoogleTVDevice,
// OccupancySensorDevice,
// OnOffLightDevice,
// OnOffLightSwitchDevice,
// OnOffPluginUnitDevice,
// OnOffSensorDevice,
// RootNodeDevice,
// SpeakerDevice,
// ThermostatDevice,
)
// List of supported device traits by this app:
val supportedTraits: List<TraitFactory<out Trait>> = listOf(
// TODO: 4.1.2 - Non-registered traits will be unsupported
// AreaAttendanceState,
// AreaPresenceState,
// Assistant,
// AssistantBroadcast,
// AssistantFulfillment,
// BasicInformation,
// BooleanState,
// OccupancySensing,
// OnOff,
// Notification,
// LevelControl,
// TemperatureControl,
// TemperatureMeasurement,
// Thermostat,
// Time,
// Volume,
)
}
Инициализируйте объект HomeClient
Все приложения, использующие Home API, инициализируют объект HomeClient
, который является основным интерфейсом взаимодействия с API. Мы подготавливаем этот объект в инициализаторе класса HomeApp
( HomeApp.kt
).
// Registry to record device types and traits used in this app:
val registry = FactoryRegistry(
types = supportedTypes,
traits = supportedTraits
)
// Configuration options for the HomeClient:
val config = HomeConfig(
coroutineContext = Dispatchers.IO,
factoryRegistry = registry
)
// Initialize the HomeClient, which is the primary object to use all Home APIs:
homeClient = Home.getClient(context = context, homeConfig = config)
Сначала мы создаём FactoryRegistry
, используя поддерживаемые типы и трейты, которые мы определили ранее. Затем, используя этот реестр, мы инициализируем HomeConfig
, содержащий конфигурацию, необходимую для запуска API. Затем мы используем вызов Home.getClient(...)
для получения экземпляра HomeClient
.
Все наше взаимодействие с Home API будет осуществляться через объект HomeClient
.
Используйте API разрешений
Аутентификация пользователей для API Home осуществляется через API Permissions. Исходный файл PermissionsManager.kt
приложения-образца содержит код для аутентификации пользователей. Раскомментируйте содержимое функций checkPermissions(...)
и requestPermissions(...)
, чтобы включить разрешения для приложения-образца.
Регистрация:
homeClient.registerActivityResultCallerForPermissions(activity)
Запуск:
try {
val result: PermissionsResult
result = homeClient.requestPermissions(forceLaunch = true)
when (result.status) {
PermissionsResultStatus.SUCCESS -> // Success Case
PermissionsResultStatus.CANCELLED -> // User Cancelled
PermissionsResultStatus.ERROR -> // Some Error
else -> // Unsupported Case
}
}
catch (e: HomeException) { ... }
Проверка:
try {
val state: PermissionsState
state = homeClient.hasPermissions().first { state ->
state != PermissionsState.PERMISSIONS_STATE_UNINITIALIZED
}
when (state) {
PermissionsState.GRANTED -> // Signed In
PermissionsState.NOT_GRANTED -> // Not Signed In
PermissionsState.PERMISSIONS_STATE_UNAVAILABLE -> // ...
PermissionsState.PERMISSIONS_STATE_UNINITIALIZED -> // ...
else -> // Unsupported case
}
}
catch (e: HomeException) { ... }
Подписка:
homeClient.hasPermissions().collect( { state ->
// Track the changes on state
} )
Раскомментируйте шаг 4.3.1 в PermissionsManager.kt
, чтобы включить код, запрашивающий разрешения:
fun requestPermissions() {
scope.launch {
try {
// TODO: 4.3.1 - Request the permissions from the Permissions API
// // Request permissions from the Permissions API and record the result:
// val result: PermissionsResult = client.requestPermissions(forceLaunch = true)
// // Adjust the sign-in status according to permission result:
// if (result.status == PermissionsResultStatus.SUCCESS)
// isSignedIn.emit(true)
// // Report the permission result:
// reportPermissionResult(result)
}
catch (e: HomeException) { MainActivity.showError(this, e.message.toString()) }
}
}
Теперь запустите приложение на телефоне, следуя инструкциям, и дайте разрешения. Вы должны увидеть следующее:
Сообщение «Загрузка» никогда не исчезает, но это потому, что мы не реализовали код для чтения структуры и устройств. Мы сделаем это в следующем разделе.
5. Понимание модели данных
В Home API модель данных состоит из:
-
Structure
представляет собой дом, содержащий комнаты и устройства. -
Room
является частью конструкции и содержит устройства. - Устройства (определяемые как
HomeDevice
) могут быть назначены строению (или дому) или комнате в строении. - Устройства состоят из одного или нескольких экземпляров
DeviceType
. -
DeviceType
состоит из экземпляровTrait
. -
Trait
состоит из экземпляровAttribute
(для чтения/записи), экземпляровCommand
(для управления атрибутами) и экземпляровEvent
(для чтения или подписки на записи прошлых изменений). - Экземпляры
Automation
являются частью структуры и используют домашние метаданные и устройства для автоматизации задач в доме.
В этом разделе вы узнаете, как разработать исходный код, демонстрирующий, как использовать API структур для анализа и визуализации структур вашего дома, комнат, устройств и т. д.
Прочитать структуры
Архитектура Home API основана на Kotlin Flows для потоковой передачи объектов модели данных (например, Structure
, HomeDevice
и т. д.). Разработчики подписываются на Flow
, чтобы получить все объекты, содержащиеся в объекте (например, Structure
, Room
и т. д.).
Чтобы получить все структуры, вызовите функцию structures()
, которая возвращает поток структур. Затем вызовите функцию list для потока, чтобы получить все структуры, которыми владеет пользователь.
// Get the a snapshot of all structures from the current homeClient
val allStructures : Set<Structure> =
homeClient.structures() // HomeObjectsFlow<Structure>
.list() // Set<Structure>
Руководство по архитектуре приложений настоятельно рекомендует использовать современный подход реактивного программирования для улучшения потока данных и управления состоянием приложения.
Вот как пример приложения соответствует стилю реактивного кодирования:
- Модели представлений (например,
StructureViewModel
иDeviceViewModel
как держатели состояний) подписываются на потоки из Home API SDK для получения изменений значений и поддержания последних состояний. - Представления (такие как
StructureView
иDeviceView
) подписываются на модели представлений, чтобы получать состояния и отображать пользовательский интерфейс для отражения этих изменений. - Когда пользователь нажимает кнопку на представлении (например, кнопку «Вкл.» на осветительном устройстве), события запускают функции модели представления, которые вызывают соответствующие функции Home API (например, команду
On
свойстваOnOff
).
На шаге 5.1.1 в HomeAppViewModel.kt
мы подписываемся на события изменения структуры, вызывая функцию collect()
. Раскомментируйте раздел, который проходит по structureSet
, возвращаемому ответом API Structures и передаваемому в StateFlow
StructureViewModel's
. Это позволяет приложению отслеживать изменения состояния структуры:
private suspend fun subscribeToStructures() {
// TODO: 5.1.1 - Subscribe the structure data changes
// // Subscribe to structures returned by the Structures API:
// homeApp.homeClient.structures().collect { structureSet ->
// val structureVMList: MutableList<StructureViewModel> = mutableListOf()
// // Store structures in container ViewModels:
// for (structure in structureSet) {
// structureVMList.add(StructureViewModel(structure))
// }
// // Store the ViewModels:
// structureVMs.emit(structureVMList)
//
// // If a structure isn't selected yet, select the first structure from the list:
// if (selectedStructureVM.value == null && structureVMList.isNotEmpty())
// selectedStructureVM.emit(structureVMList.first())
//
// }
}
В DevicesView.kt
приложение подписывается на StateFlow StructureViewModel'sStateFlow,
который запускает перекомпоновку пользовательского интерфейса при изменении данных структуры. Раскомментируйте исходный код в шаге 5.1.2, чтобы отобразить список структур в виде раскрывающегося меню:
val structureVMs: List<StructureViewModel> = homeAppVM.structureVMs.collectAsState().value
...
DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
// TODO: 5.1.2 - Show list of structures in DropdownMenu
// for (structure in structureVMs) {
// DropdownMenuItem(
// text = { Text(structure.name) },
// onClick = {
// scope.launch { homeAppVM.selectedStructureVM.emit(structure) }
// expanded = false
// }
// )
// }
}
...
Запустите приложение ещё раз. При нажатии на стрелку должно появиться меню:
Разбор структуры
Следующий шаг — обойти объекты дома в структуре. Извлечь комнаты из структуры:
val rooms: Set<Room>
rooms = structure.rooms().list()
Затем вы можете перемещаться по комнатам и находить устройства:
val devices: Set<HomeDevice>
devices = room.devices().list()
Важно: в модели данных Home API структура может содержать устройства, которые не назначены в комнату , поэтому обязательно включите в свое приложение также и устройства без комнат:
val devicesWithoutRooms: MutableSet<HomeDevice> = mutableSetOf()
for (device in structure.devices().list())
if (device.roomId == null)
devicesWithoutRooms.add(device)
Опять же, в существующем примере кода мы подписываемся на поток для получения актуального списка комнат и устройств. Проверьте код на шагах 5.2.1 и 5.2.2 в исходном файле StructureViewModel.kt
и раскомментируйте его, чтобы включить подписку на данные комнат:
val roomVMs : MutableStateFlow<List<RoomViewModel>>
val deviceVMs : MutableStateFlow<List<DeviceViewModel>>
val deviceVMsWithoutRooms : MutableStateFlow<List<DeviceViewModel>>
private suspend fun subscribeToRooms() {
// TODO: 5.2.1 - Subscribe the room data changes
// // Subscribe to changes on rooms:
// structure.rooms().collect { roomSet ->
// val roomVMs = mutableListOf<RoomViewModel>()
// // Store rooms in container ViewModels:
// for (room in roomSet) {
// roomVMs.add(RoomViewModel(room))
// }
// // Store the ViewModels:
// this.roomVMs.emit(roomVMs)
// }
}
private suspend fun subscribeToDevices() {
// TODO: 5.2.2 - Subscribe the device data changes in a structure
// // Subscribe to changes on devices:
// structure.devices().collect { deviceSet ->
// val deviceVMs = mutableListOf<DeviceViewModel>()
// val deviceWithoutRoomVMs = mutableListOf<DeviceViewModel>()
// // Store devices in container ViewModels:
// for (device in deviceSet) {
// val deviceVM = DeviceViewModel(device)
// deviceVMs.add(deviceVM)
// // For any device that's not in a room, additionally keep track of a separate list:
// if (device.roomId == null)
// deviceWithoutRoomVMs.add(deviceVM)
// }
// // Store the ViewModels:
// this.deviceVMs.emit(deviceVMs)
// deviceVMsWithoutRooms.emit(deviceWithoutRoomVMs)
// }
}
Раскомментируйте шаги 5.2.3 и 5.2.4 в исходном файле DevicesView.kt
, чтобы отобразить список комнат в виде меню:
val selectedRoomVMs: List<RoomViewModel> =
selectedStructureVM.roomVMs.collectAsState().value
...
for (roomVM in selectedRoomVMs) {
// TODO: 5.2.3 - Render the list of rooms
// RoomListItem(roomVM)
// TODO: 5.2.4 - Render the list of devices in a room
// val deviceVMsInRoom: List<DeviceViewModel> = roomVM.deviceVMs.collectAsState().value
//
// for (deviceVM in deviceVMsInRoom) {
// DeviceListItem(deviceVM, homeAppVM)
// }
}
Теперь, когда у вас есть устройства, мы научимся с ними работать.
6. Работа с устройствами
API Home используют объект HomeDevice
для описания устройства и его возможностей. Разработчики могут подписываться на атрибуты устройства и использовать их для представления устройств умного дома в своих приложениях.
Чтение состояний устройства
Объект HomeDevice
представляет собой набор статических значений, таких как имя устройства или состояние подключения. Разработчик может получить эти значения вскоре после получения устройства через API:
val id: String = device.id.id
val name: String = device.name
val connectivity: ConnectivityState =
device.sourceConnectivity.connectivityState
Чтобы получить информацию о возможностях устройства, необходимо получить типы и характеристики из HomeDevice
. Для этого можно подписаться на поток типов устройств следующим образом и получить характеристики из типов устройств:
device.types().collect { typeSet ->
var primaryType : DeviceType = UnknownDeviceType()
for (typeInSet in typeSet)
if (typeInSet.metadata.isPrimaryType)
primaryType = typeInSet
val traits: List<Trait> = mutableListOf()
for (trait in primaryType.traits())
if (trait.factory in myTraits)
traits.add(trait)
for (trait in traits)
parseTrait(trait, primaryType)
}
Каждое устройство содержит набор поддерживаемых DeviceType
(объединенных возможностей), которые можно получить с помощью device.types()
. Эти типы устройств содержат характеристики, которые можно получить с помощью type.traits()
. Каждое устройство отмечает один из своих типов как основной (что можно проверить с помощью type.metadata.isPrimaryType
), который должен быть представлен в вашем приложении. Чтобы обеспечить пользователям полноценный опыт, мы рекомендуем просматривать все возвращаемые типы и интегрировать все доступные характеристики.
После извлечения признака вы можете проанализировать его, используя для интерпретации значений следующую функцию:
fun <T : Trait?> parseTrait(trait : T, type: DeviceType) {
val status : String = when (trait) {
is OnOff -> { if (trait.onOff) "On" else "Off" }
is LevelControl -> { trait.currentLevel.toString() }
is BooleanState -> {
when (type.factory) {
ContactSensorDevice -> {
if (trait.stateValue) "Closed"
else "Open"
}
else -> ...
}
}
else -> ...
}
}
Обратите внимание, что могут существовать различия в том, что представляет собой характеристика, в зависимости от типа устройства, на котором она представлена (см. BooleanState
в предыдущем примере), поэтому вам необходимо знать контекст каждого типа устройства, чтобы понять, что на самом деле представляют их характеристики.
Раскомментируйте шаги 6.1.1 и 6.1.2 в исходном файле DeviceViewModel.kt
для получения состояний:
private suspend fun subscribeToType() {
// Subscribe to changes on device type, and the traits/attributes within:
device.types().collect { typeSet ->
// Container for the primary type for this device:
var primaryType : DeviceType = UnknownDeviceType()
...
// TODO: 6.1.1 - Determine the primary type for this device
// // Among all the types returned for this device, find the primary one:
// for (typeInSet in typeSet)
// if (typeInSet.metadata.isPrimaryType)
// primaryType = typeInSet
//
// // Optional: For devices with a single type that did not define a primary:
// if (primaryType is UnknownDeviceType && typeSet.size == 1)
// primaryType = typeSet.first()
// Container for list of supported traits present on the primary device type:
val supportedTraits: List<Trait> = getSupportedTraits(primaryType.traits())
...
}
fun getSupportedTraits(traits: Set<Trait>) : List<Trait> {
val supportedTraits: MutableList<Trait> = mutableListOf()
// TODO: 6.1.2 - Get only the supported traits for this device
// for (trait in traits)
// if (trait.factory in HomeApp.supportedTraits)
// supportedTraits.add(trait)
return supportedTraits
}
Раскомментируйте шаг 6.1.3 в DeviceView.kt
, чтобы отобразить свойство OnOff, включая его имя и статус, в виде String
:
Box (Modifier.padding(horizontal = 24.dp, vertical = 8.dp)) {
when (trait) {
is OnOff -> {
// TODO: 6.1.3 - Render controls based on the trait type
// Column (Modifier.fillMaxWidth()) {
// Text(trait.factory.toString(), fontSize = 20.sp)
// Text(DeviceViewModel.getTraitStatus(trait, type), fontSize = 16.sp)
// }
...
}
is LevelControl -> {
...
}
is BooleanState -> {
...
}
is OccupancySensing -> {
...
}
...
}
Если вы сейчас запустите приложение с поддерживаемыми типами устройств (например, устройством Light), оно должно отобразить актуальные состояния для всех устройств.
Выдача команд устройству
Для выдачи команд устройствам API Home предоставляют удобные функции для объектов Trait, такие как trait.on()
или trait.moveToLevel(...)
:
fun <T : Trait?> issueCommand(trait : T) {
when (trait) {
is OnOff -> {
// trait.on()
// trait.off()
}
is LevelControl -> {
// trait.moveToLevel(...)
// trait.moveToLevelWithOnOff(...)
}
}
}
Совет: как только вы определите тип признака, воспользуйтесь функцией автозаполнения Android Studio, чтобы узнать, какие действия доступны для взаимодействия с признаком.
Раскомментируйте шаг 6.2.1 в DeviceView.kt
чтобы добавить функциональные элементы управления в приложение:
Box (Modifier.padding(horizontal = 24.dp, vertical = 8.dp)) {
when (trait) {
is OnOff -> {
....
// TODO: 6.2.1 - Render controls based on the trait type
// Switch (checked = (trait.onOff == true), modifier = Modifier.align(Alignment.CenterEnd),
// onCheckedChange = { state ->
// scope.launch { if (state) trait.on() else trait.off() }
// },
// enabled = isConnected
// )
}
Если вы запустите приложение сейчас, оно позволит вам управлять реальными физическими устройствами.
Если нажать кнопку включения/выключения на лампочке, устройство должно включиться.
Дополнительную информацию об управлении устройствами см. в разделе Управление устройствами на Android .
7. Комиссионные устройства
API Commissioning позволяет разработчикам добавлять устройства в экосистему Google Home и управлять ими с помощью API Home. Поддерживаются только устройства Matter. В этом разделе мы рассмотрим, как включить функцию Commissioning в ваших приложениях.
Прежде чем приступить к работе с этим разделом, убедитесь, что выполнены следующие предварительные условия:
- В приложение Google Home добавлен Google Hub с поддержкой Matter, расположенный в той же сети, что и ваш телефон Android.
- Вы создали проект разработчика в консоли разработчика Google Home с VID
0xFFF1
и PID0x8000
.
Если у вас есть физическое устройство Matter с QR-кодом для ввода в эксплуатацию, вы можете перейти к разделу «Включить API для ввода в эксплуатацию» . В противном случае перейдите к следующему разделу, где мы рассмотрим, как использовать приложение Matter Virtual Device (MVD) для создания виртуальных устройств, готовых к вводу в эксплуатацию.
Необязательно: Подготовьте устройство для комиссии Matter
Самый простой способ подготовить комиссионное устройство Matter — использовать эмулированное устройство, предоставляемое приложением Matter Virtual Device (MVD).
После установки MVD и настройки брандмауэра запустите MVD:
Создайте устройство OnOff. Обратите внимание, что оно ещё не введено в эксплуатацию — вы введёте его в эксплуатацию позже в ходе этой лабораторной работы.
Включить API ввода в эксплуатацию
API для ввода в эксплуатацию работает вне Activity приложения, поэтому его необходимо обрабатывать иначе, чем другие API Home. Чтобы подготовить приложение к вводу в эксплуатацию, вам понадобятся две переменные.
Одна переменная — ActivityResultLauncher
, которая используется для отправки намерения ввода в эксплуатацию и управления обратным вызовом результата. Другая переменная — CommissioningResult
, которая представляет собой объект, используемый для хранения результата ввода в эксплуатацию. Настройка ввода в эксплуатацию показана в следующем примере:
var launcher: ActivityResultLauncher<IntentSenderRequest>
lateinit var commissioningResult: CommissioningResult?
launcher = activity.registerForActivityResult(StartIntentSenderForResult()) { result ->
try {
commissioningResult = CommissioningResult.fromIntentSenderResult(
result.resultCode, result.data)
} catch (exception: ApiException) {
// Catch any issues
}
}
После настройки процесса ввода в эксплуатацию вам нужно будет создать намерение ввода в эксплуатацию и запустить его с помощью средства запуска, созданного в предыдущем примере. Мы рекомендуем поместить намерение и средство запуска в специальную функцию, как показано ниже. Специальную функцию можно привязать к элементу пользовательского интерфейса (например, к кнопке «+Добавить устройство ») и вызывать по запросу пользователя:
fun requestCommissioning() {
// Retrieve the onboarding payload used when commissioning devices:
val payload = activity.intent?.getStringExtra(Matter.EXTRA_ONBOARDING_PAYLOAD)
scope.launch {
// Create a commissioning request to store the device in Google's Fabric:
val request = CommissioningRequest.builder()
.setStoreToGoogleFabric(true)
.setOnboardingPayload(payload)
.build()
// Initialize client and sender for commissioning intent:
val client: CommissioningClient = Matter.getCommissioningClient(context)
val sender: IntentSender = client.commissionDevice(request).await()
// Launch the commissioning intent on the launcher:
launcher.launch(IntentSenderRequest.Builder(sender).build())
}
}
Раскомментируйте шаг 7.1.1 в CommissioningManager.kt
, чтобы включить возможность ввода в эксплуатацию и заставить работать кнопку +Добавить устройство в примере приложения.
// Called by +Add Device button in DeviceView.kt
fun requestCommissioning() {
// Retrieve the onboarding payload used when commissioning devices:
val payload = activity.intent?.getStringExtra(Matter.EXTRA_ONBOARDING_PAYLOAD)
// TODO: 7.1.1 - Launch the commissioning intent
// scope.launch {
// // Create a commissioning request to store the device in Google's Fabric:
// val request = CommissioningRequest.builder()
// .setStoreToGoogleFabric(true)
// .setOnboardingPayload(payload)
// .build()
// // Initialize client and sender for commissioning intent:
// val client: CommissioningClient = Matter.getCommissioningClient(context)
// val sender: IntentSender = client.commissionDevice(request).await()
// // Launch the commissioning intent on the launcher:
// launcher.launch(IntentSenderRequest.Builder(sender).build())
// }
}
Запуск этой функции должен запустить процесс ввода в эксплуатацию, в результате которого должен появиться экран, подобный следующему снимку экрана:
Понять процесс ввода в эксплуатацию
Процесс ввода в эксплуатацию включает в себя ряд экранов, которые помогают пользователю добавить устройство в свою учетную запись Google:
Пользователям будет предоставлен сканер QR-кодов, который можно использовать для сканирования QR-кодов с устройств Matter. Далее процесс выполнит следующие этапы: отображение пользовательского соглашения, обнаружение и настройка устройства, а также присвоение ему имени. После завершения процесса фокус снова переключится на приложение, а результат настройки будет передан в функцию обратного вызова, разработанную в предыдущем разделе.
Одним из преимуществ Commissioning API является то, что весь UX-процесс обрабатывается SDK, что позволяет разработчикам быстро приступить к работе. Это также обеспечивает пользователям единообразный интерфейс при добавлении устройств в разные приложения.
Более подробную информацию об API ввода в эксплуатацию можно найти на странице API ввода в эксплуатацию на Android .
8. Поздравляем!
Поздравляем! Вы успешно создали приложение для Android с использованием API Google Home. В этой практической работе вы изучили API разрешений, устройств, структур и ввода в эксплуатацию. В следующей практической работе « Создание расширенных функций автоматизации с использованием API Google Home на Android» мы изучим API автоматизации и обнаружения, а также завершим разработку приложения.
Мы надеемся, что вам понравится создавать приложения, которые творчески управляют устройствами в экосистеме Google Home.
Следующие шаги
- Продолжайте изучать API Home на Android, выполнив вторую лабораторную работу из этой серии: создание расширенных автоматизаций с использованием API Home на Android .
- Вы можете обратиться к нам с любыми рекомендациями или сообщить о любых проблемах через раздел поддержки Smart Home в системе отслеживания проблем .