Создайте мобильное приложение с помощью Home API на Android. Создайте мобильное приложение с помощью Home API на Android.

1. Прежде чем начать

API Google Home предоставляют разработчикам Android набор библиотек для работы с экосистемой Google Home. Благодаря этим новым API разработчики могут создавать приложения, которые позволяют беспрепятственно вводить в эксплуатацию и управлять устройствами умного дома.

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

Google предоставляет разработчикам демонстрационное приложение для Android, позволяющее получить доступ к работающему примеру использования API Google Home. Данный практический пример основан на ветке демонстрационного приложения и покажет, как использовать API разрешений, ввода в эксплуатацию, устройств и структуры.

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

Что вы узнаете

  • Как создать Android-приложение с использованием API Google Home, следуя лучшим практикам.
  • Как использовать API-интерфейсы Device и Structure для представления и управления умным домом.
  • Как использовать API ввода в эксплуатацию для добавления устройств в экосистему Google Home.

Дополнительно: обустройте свой дом

Перед использованием API Google Home вам необходимо настроить дом в своей учетной записи Google с помощью приложения Google Home и добавить несколько устройств. В этом разделе описывается, как это сделать с помощью Google Home Playground , который предоставляет виртуальные устройства для умного дома.

Откройте сайт home-playground.withgoogle.com в своем веб-браузере, войдите в систему с помощью своей учетной записи Google и проверьте, отображаются ли следующие эмулируемые устройства:

  • розетка 1: штекер включения/выключения
  • light2: Диммируемый светильник
  • light3: Индикатор включения/выключения
  • ac3: Кондиционер
  • жалюзи4: Оконные покрытия
  • стиральная машина5: Умная стиральная машина

914d23a42b72df8f.png

Откройте приложение Google Home на своем мобильном устройстве, нажмите кнопку «Добавить » и выберите «Работает с Google Home». Найдите в списке «игровая площадка», затем выберите проект «Google Home Playground» и нажмите « Продолжить» .

e9ec257b0d9b1ed2.png29fd7416e274d216.pngd974573af0611fd8.png

В Google Home Playground отобразится страница авторизации учетной записи. Нажмите «Авторизовать» или «Войти через Google» . В мобильном приложении вы увидите все устройства, которые вы настроили через веб-приложение.

13108a3a15440151.png8791a6d33748f7c8.png

Выберите все устройства и завершите процесс настройки. Вернувшись на главную страницу, вы увидите все доступные устройства.

2b021202e6fd1750.png

Устройства из этого списка, на которые распространяется поддержка Google Home, теперь доступны для использования с API Google Home.

2. Настройте свой проект.

На следующей диаграмме представлена ​​архитектура приложения Home APIs:

Архитектура API для домашней страницы в приложении Android

  • Код приложения: Основной код, над которым работают разработчики для создания пользовательского интерфейса приложения и логики взаимодействия с SDK Home APIs.
  • Home APIs SDK: Предоставляемый Google Home APIs SDK работает с сервисом Home APIs в GMSCore для управления устройствами умного дома. Разработчики создают приложения, работающие с Home APIs, путем включения их в состав Home APIs SDK.
  • GMSCore на Android: GMSCore, также известный как Google Play Services, — это платформа Google, предоставляющая основные системные сервисы, обеспечивающие ключевую функциональность на всех сертифицированных устройствах Android. Модуль Home в Google Play Services содержит сервисы, взаимодействующие с 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 в разделе «Создание приложения» .

32f2b3c0cd80fcf1.png

Когда приложение успешно запустится на вашем телефоне, вы увидите главную страницу демонстрационного приложения. Однако вы не сможете войти в систему, пока не настроите аутентификацию OAuth и не реализуете недостающие компоненты с помощью API разрешений.

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.

Все приложения, использующие API Home, инициализируют объект 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 разрешений. Исходный файл 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()) }
    }
}

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

c263dcee4e945bf1.pngf518cfd1fdb8a9d8.png59937372f28c472f.png383073ae57d2ced4.png89f774a2ba6898ae.png

Сообщение "Загрузка" никогда не исчезает, но это потому, что мы еще не реализовали код, который считывает структуру и устройства. Мы сделаем это в следующем разделе.

5. Разберитесь в модели данных.

В API Home модель данных состоит из:

  • Structure представляет собой дом, включающий комнаты и бытовую технику.
  • Room является частью конструкции и содержит в себе оборудование.
  • Устройства (обозначаемые как HomeDevice ) могут быть привязаны к зданию (или дому) или к комнате в этом здании.
  • Устройства состоят из одного или нескольких экземпляров DeviceType .
  • DeviceType состоит из экземпляров Trait .
  • Trait состоит из экземпляров Attribute (для чтения/записи), экземпляров Command (для управления атрибутами) и экземпляров Event (для чтения или подписки на записи о прошлых изменениях).
  • Экземпляры Automation являются частью структуры и используют метаданные дома и устройства для автоматизации задач в доме.

76d35b44d5a8035e.png

В этом разделе вы узнаете, как разработать исходный код, демонстрирующий использование 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 , выступающие в качестве держателей состояния) подписываются на потоки данных из SDK Home API, чтобы получать изменения значений и поддерживать актуальность состояний.
  • Представления (например, StructureView и DeviceView ) подписываются на модели представлений, чтобы получать состояния и отображать пользовательский интерфейс, отражающий эти изменения.
  • Когда пользователь нажимает кнопку на представлении (например, кнопку «Вкл.» на световом устройстве), события запускают функции модели представления, которые вызывают соответствующие функции API Home (например, команду « On » трейта OnOff ).

На шаге 5.1.1 в HomeAppViewModel.kt мы подписываемся на события изменения структуры, вызывая функцию collect() . Раскомментируйте раздел, который обрабатывает structureSet , возвращаемый ответом от Structures API и передаваемый в 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
//          }
//      )
//  }
}
...

Запустите приложение ещё раз. При нажатии на стрелку вы должны увидеть меню:

f1fc2be1cb6436b6.png

Разберите структуру

Следующий шаг — обойти домашние объекты в структуре. Извлечь комнаты из структуры:

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)
//   }
}

Теперь, когда у вас есть эти устройства, мы научимся с ними работать.

e715ddda50e04839.png

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), оно должно отобразить актуальное состояние всех устройств.

1bd8b3b2796c4c7a.png

Выдавайте команды устройству

Для отправки команд устройствам 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
//   )
}

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

Если вы нажмете на кнопку включения/выключения на лампочке, устройство должно включиться.

c8ed3ecf5031546e.png

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

7. Ввод в эксплуатацию устройств

API для ввода устройств в эксплуатацию позволяет разработчикам добавлять устройства в экосистему Google Home и делать их доступными для управления с помощью API Home. Поддерживаются только устройства Matter. В этом разделе мы рассмотрим, как включить ввод устройств в эксплуатацию в ваших приложениях.

Перед началом работы над этим разделом убедитесь, что выполнены следующие предварительные условия:

Если у вас есть физическое устройство Matter с QR-кодом для ввода в эксплуатацию, вы можете перейти к разделу «Включение API ввода в эксплуатацию ». В противном случае, перейдите к следующему разделу, где мы обсудим, как использовать приложение Matter Virtual Device (MVD) для создания виртуальных устройств, подлежащих вводу в эксплуатацию.

Дополнительно: Подготовьте устройство, подлежащее сдаче в эксплуатацию.

Простейший способ подготовить устройство Matter к вводу в эксплуатацию — использовать эмулированное устройство, предоставляемое приложением Matter Virtual Device (MVD).

После установки MVD и настройки брандмауэра запустите MVD:

b20283893073ac1b.png

Создайте устройство OnOff. Обратите внимание, что оно еще не введено в эксплуатацию — вы сделаете это позже в ходе этого практического занятия.

5f4855b808312898.png

Включите 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())
// }
}

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

baae45588f460664.png

Разберитесь в процессе ввода в эксплуатацию.

Процесс ввода в эксплуатацию включает в себя набор экранов, которые помогают пользователю добавить устройство в свою учетную запись Google:

2fb0404820d4a035.png3cbfa8ff9cfd5ee4.pnga177c197ee7a67bf.png3fdef24672c77c0.pngdec8e599f9aa119.png

Пользователей встретит сканер QR-кодов, который они смогут использовать для сканирования QR-кодов с устройств Matter. Затем процесс будет включать отображение пользовательского соглашения, обнаружение и ввод в эксплуатацию устройства, а также присвоение ему имени. После завершения процесса фокус вернется к приложению, и результат ввода в эксплуатацию будет передан в функцию обратного вызова, разработанную нами в предыдущем разделе.

Одним из преимуществ API для ввода устройств в эксплуатацию является то, что обработка пользовательского интерфейса осуществляется SDK, поэтому разработчики могут очень быстро приступить к работе. Это также обеспечивает пользователям единообразный опыт при добавлении устройств в различные приложения.

Чтобы узнать больше об API ввода в эксплуатацию, посетите страницу «API ввода в эксплуатацию на Android» .

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

Поздравляем! Вы успешно создали Android-приложение, используя API Google Home. В ходе этого практического занятия вы изучили API разрешений, устройств, структур и ввода в эксплуатацию. В следующем практическом занятии, «Создание сложных автоматизаций с использованием API Home на Android» , мы изучим API автоматизации и обнаружения и завершим создание приложения.

Мы надеемся, что вам понравится создавать приложения, которые позволяют творчески управлять устройствами в экосистеме Google Home.

Следующие шаги