1. Прежде чем начать
API Google Home предоставляют набор библиотек для разработчиков Android, чтобы они могли подключиться к экосистеме Google Home. С помощью этих новых API разработчики могут создавать приложения, которые легко вводят в эксплуатацию и контролируют устройства умного дома.
Google предоставляет Android Sample App для разработчиков, которые хотят получить доступ к рабочему примеру с использованием API Google Home. Эта кодовая лаборатория основана на ветви Sample App, которая проведет вас через то, как использовать 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. Найдите «playground» в списке, затем выберите проект «Google Home Playground» и нажмите Продолжить .
Google Home Playground покажет вам страницу авторизации учетной записи. Нажмите Авторизовать или Войти с Google . Вы увидите все устройства, которые вы настроили из веб-приложения в мобильном приложении.
Выберите все устройства и завершите процесс настройки. Вернувшись на главную страницу, вы увидите все доступные устройства.
Поддерживаемые устройства из списка теперь доступны для использования с API Google Home.
2. Настройте свой проект
Следующая диаграмма иллюстрирует архитектуру приложения Home API:
- Код приложения: основной код, над которым работают разработчики для создания пользовательского интерфейса приложения и логики взаимодействия с SDK Home API.
- Home APIs SDK: Home APIs SDK, предоставляемый Google, работает с Home APIs Service в GMSCore для управления умными домашними устройствами. Разработчики создают приложения, которые работают с Home APIs, объединяя их с Home APIs SDK.
- GMSCore на Android: GMSCore, также известный как Google Play services, — это платформа Google, которая предоставляет основные системные службы, обеспечивая ключевые функции на всех сертифицированных устройствах Android. Домашний модуль служб Google Play содержит службы, которые взаимодействуют с API Home.
Настройте Home SDK
Чтобы получить последнюю версию SDK, следуйте инструкциям в разделе Настройка SDK .
Получить образец приложения
Исходный код для Sample App доступен на GitHub. Эта codelab использует примеры из ветки codelab-branch-1
Sample App.
Перейдите туда, где вы хотите сохранить проект, и клонируйте ветку 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 разрешений.
Определите поддерживаемые типы и характеристики
При разработке приложения вам необходимо явно указать, какие типы устройств и характеристики приложение будет поддерживать. В Sample App мы делаем это, определяя статические списки в объекте-компаньоне в 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
.
Все наше взаимодействие с API Home будет осуществляться через объект HomeClient
.
Используйте API разрешений
Аутентификация пользователя для API Home выполняется через API Permissions. Исходный файл PermissionsManager.kt
приложения Sample App содержит код для аутентификации пользователя. Раскомментируйте содержимое функций checkPermissions(...)
и requestPermissions(...)
, чтобы включить разрешения для приложения Sample App.
Регистрация:
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. Понять модель данных
В API Home модель данных состоит из:
-
Structure
представляет собой дом, содержащий комнаты и устройства. -
Room
является частью конструкции и содержит устройства. - Устройства (определяемые как
HomeDevice
) могут быть назначены строению (или дому) или комнате в строении. - Устройства состоят из одного или нескольких экземпляров
DeviceType
. -
DeviceType
состоит из экземпляровTrait
. -
Trait
состоит из экземпляровAttribute
(для чтения/записи), экземпляровCommand
(для управления атрибутами) и экземпляровEvent
(для чтения или подписки на записи прошлых изменений). - Экземпляры
Automation
являются частью структуры и используют метаданные и устройства дома для автоматизации задач в доме.
В этом разделе вы узнаете, как разработать исходный код, демонстрирующий использование API структур для анализа и визуализации структур вашего дома, комнат, устройств и т. д.
Прочитать структуры
Дизайн API Home основан на 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
, как держатели состояний) подписываются на потоки из SDK Home API для получения изменений значений и поддержания последних состояний. - Представления (например,
StructureView
иDeviceView
) подписываются на модели представлений, чтобы получать состояния и отображать пользовательский интерфейс для отражения этих изменений. - Когда пользователь нажимает кнопку на представлении (например, кнопку «Вкл.» на осветительном устройстве), события запускают функции модели представления, которые вызывают соответствующие функции API Home (например, команду
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
приложение подписывается на 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()
Важно: в модели данных API Home структура может содержать устройства, которые не назначены ни одной комнате , поэтому обязательно включите в свое приложение также и устройства без комнат:
val devicesWithoutRooms: MutableSet<HomeDevice> = mutableSetOf()
for (device in structure.devices().list())
if (!device.isInRoom)
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.isInRoom)
// 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. Комиссионные устройства
Commissioning API позволяет разработчикам добавлять устройства в экосистему Google Home и делать их доступными для управления с помощью Home API. Поддерживаются только устройства Matter. В этом разделе мы рассмотрим, как можно включить комиссию устройств в своих приложениях.
Прежде чем приступить к работе с этим разделом, убедитесь, что выполнены следующие предварительные условия:
- В приложение Google Home добавлен Google Hub с поддержкой Matter, расположенный в той же сети, что и ваш телефон Android.
- Вы создали проект разработчика в консоли разработчика Google Home с VID
0xFFF1
и PID0x8000
.
Если у вас есть физическое устройство Matter с QR-кодом для ввода в эксплуатацию, вы можете перейти к разделу Включить API ввода в эксплуатацию . В противном случае перейдите к следующему разделу, где мы обсудим, как можно использовать приложение Matter Virtual Device (MVD) для создания виртуальных устройств с возможностью ввода в эксплуатацию.
Необязательно: Подготовьте устройство, подлежащее комиссии
Самый простой способ подготовить комиссионное устройство Matter — использовать эмулированное устройство, предоставляемое приложением Matter Virtual Device (MVD).
После установки MVD и настройки брандмауэра запустите MVD:
Создайте устройство OnOff. Обратите внимание, что оно еще не введено в эксплуатацию — вы введете его в эксплуатацию позже в этой кодовой лаборатории.
Включить API ввода в эксплуатацию
Commissioning API работает вне Activity приложения, поэтому Commissioning необходимо обрабатывать иначе, чем другие Home API. Чтобы подготовить приложение к Commissioning, вам нужны две переменные.
Одна переменная — 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 Home на Android» мы изучим API автоматизации и обнаружения и завершим приложение.
Мы надеемся, что вам понравится создавать приложения, которые творчески управляют устройствами в экосистеме Google Home.
Следующие шаги
- Продолжайте изучать API Home на Android, выполнив вторую лабораторную работу в этой серии: Создание расширенных средств автоматизации с использованием API Home на Android .
- Вы можете обратиться к нам с любыми рекомендациями или сообщить о любых проблемах через раздел поддержки Smart Home в системе отслеживания проблем .