Берегись! Скоро будут запущены новые программы Developer Preview. Подайте заявку здесь и станьте одним из первых, кто опробует новые инструменты и оставит отзыв.

Создайте Android-приложение для Matter

1. Добро пожаловать

Matter, созданный с целью унификации стандартов IoT, соединяет устройства умного дома в различных экосистемах, таких как Google Home, Zigbee, Bluetooth Mesh, Z-Wave и других.

Мобильные устройства являются центральной точкой взаимодействия с устройствами умного дома. Если вы хотите создавать собственные приложения для Android для поддержки устройств Matter, мы можем помочь вам быстро начать работу.

Образец приложения Google Home for Matter (GHSA for Matter) демонстрирует API-интерфейсы Home Mobile SDK , позволяющие пользователям вводить устройства в эксплуатацию и совместно использовать их. Вы также можете использовать пример приложения в качестве обучающего инструмента для лучшего понимания ключевых концепций Matter, а также в качестве инструмента для отладки и устранения неполадок при взаимодействии с устройствами Matter.

Что ты будешь делать

В этой лаборатории кода вы загрузите исходный код примера приложения и узнаете, как использовать Home Mobile SDK для ввода в эксплуатацию и совместного использования устройств. Вы также узнаете, как использовать ввод в эксплуатацию и библиотеки кластеров из репозитория Matter ( connectedhomeip ) .

После того как вы загрузите образец приложения, мы просмотрим исходный код в Android Studio и реализуем следующие API-интерфейсы Home Mobile SDK :

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

Что вам понадобится

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

Вам не нужен концентратор, например Google Nest Hub (2-го поколения), для ввода в эксплуатацию и управления устройствами с помощью примера приложения.

2. Настройте

Репозиторий примера приложения GitHub включает сторонние библиотеки из репозитория Matter ( connectedhomeip ) . Эти нативные библиотеки имеют размер более 50 МБ и требуют использования хранилища больших файлов Git (LFS).

Стартовое приложение codelab находится в ветке codelab . Чтобы начать работу с исходным кодом codelab, вы можете скачать ZIP-файл. Этот ZIP-файл включает нативные библиотеки Matter SDK без использования Git LFS:

Вы будете использовать этот ZIP-файл codelab для создания рабочего примера.

Версии Codelab

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

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

Зависимости

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

  • Домашний мобильный SDK .
    implementation 'com.google.android.gms:play-services-home:16.0.0'
    
  • Библиотеки Matter SDK.
    // Native libs
    implementation fileTree(dir: "third_party/connectedhomeip/libs", include: ["*.jar", "*.so"])
    
  • Материальный дизайн. Чтобы узнать больше, обратитесь к MDC-103 Android: Material Theming with Color, Elevation and Type (Kotlin) и Material Theme Builder .
    implementation 'com.google.android.material:material:1.5.0'
    
  • Proto DataStore, используемый для сохранения данных приложения. Хранилища данных и сериализаторы хранятся в java/data , включая схемы для устройств и пользовательские настройки. Чтобы узнать больше о DataStore, обратитесь к разделу Работа с Proto DataStore .
    implementation "androidx.datastore:datastore:$dataStoreVersion"
    implementation 'androidx.datastore:datastore-core:1.0.0'
    implementation 'com.google.protobuf:protobuf-javalite:3.18.0'
    
  • Hilt для сохранения данных и поддержки внедрения зависимостей.
    kapt 'com.google.dagger:hilt-compiler:2.41'
    implementation 'com.google.dagger:hilt-android:2.41'
    

Исходный код

Пользовательский интерфейс и большая часть функционала уже созданы за вас.

Для этой лаборатории кода мы добавим функциональность Matter в следующие файлы:

  • java/commissioning/AppCommissioningService : позволяет вводить устройства в среду разработки.
  • java/screens/HomeFragment и java/screens/HomeViewModel.kt : включает в себя функцию ввода в эксплуатацию Home Mobile SDK.
  • java/screens/DeviceViewModel : включает вызовы API общего доступа к устройству.

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

// CODELAB: add commissioningFunction()

Это позволяет быстро найти соответствующий раздел в кодовой лаборатории.

3. Комиссия Google

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

Важно понимать следующие концепции ввода Matter в эксплуатацию:

  • Фабрики позволяют устройствам взаимодействовать друг с другом.
  • Fabrics поддерживает общий набор уникальных учетных данных.
  • Экосистемы несут ответственность за выдачу доверенных корневых сертификатов, назначение идентификаторов структуры и присвоение уникальных идентификаторов узлов. Экосистема — это внутренняя служба уполномоченного, например Home Graph для экосистемы Google Home.
  • Устройства можно назначать более чем одной фабрике (функция нескольких администраторов).

Чтобы ввести устройство в эксплуатацию, вам потребуется использовать API CommissioningClient . Вызов .commissionDevice() возвращает IntentSender , который запускает соответствующую активность в Сервисах Google Play:

interface CommissioningClient {
  Task<IntentSender> commissionDevice(CommissioningRequest request);
}

В следующих разделах мы рассмотрим минимальный код, необходимый для ввода устройств в структуру Google.

Шаг 1: Средство запуска активности

Для обработки IntentSender из CommissioningClient вы можете использовать ActivityResultLauncher:

private lateinit var commissioningLauncher: ActivityResultLauncher<IntentSenderRequest>
commissioningLauncher = registerForActivityResult(
    StartIntentSenderForResult()
) { result: ActivityResult ->
    if (result.resultCode == RESULT_OK) {
        Timber.d(TAG, "Commissioning succeeded.")
    } else {
        Timber.d(TAG, "Commissioning failed. " + result.resultCode)
    }
}

Шаг 2: Функция ввода в эксплуатацию

Вот базовый пример, в котором используется API CommissioningClient для ввода устройства в структуру Google.

  1. Процесс ввода в эксплуатацию начинается с функции commissionDevice() . Во-первых, определяется CommissioningRequest . В этой конфигурации по умолчанию устройства вводятся в эксплуатацию только для локальной структуры Android.
  2. Matter — это точка входа для Home Mobile SDK. При следующем вызове .getCommissioningClient this (Activity) получает CommissioningClient.
  3. .commissionDevice() принимает запрос CommissioningRequest .
  4. И, наконец, вызывается .addOnSuccessListener для обработки CommissioningResult и запуска активности устройства с комиссией Google Play Services (GPS).
private fun commissionDevice() {
    val request: CommissioningRequest = CommissioningRequest.builder().build()
    Matter.getCommissioningClient(this)
        .commissionDevice(request)
        .addOnSuccessListener { result ->
            commissioningLauncher.launch(IntentSenderRequest.Builder(result).build())
        }
}

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

Далее вы узнаете, как ввести устройство в состав среды разработки.

Обзор пользовательского интерфейса во время ввода в эксплуатацию см. в Руководстве по выбору приложения Google Home for Matter .

4. Задание на разработку ткани

Устройства могут быть введены в эксплуатацию для более чем одной ткани. Для управления доверенными связями устройства хранят FabricTable , содержащую различные элементы FabricInfo , например:

  • Идентификация ткани
  • Идентификатор узла, назначенный фабрикой устройству
  • Идентификатор поставщика
  • Идентификатор ткани
  • Рабочие учетные данные устройства

Менеджер административного домена (ADM) определяет учетные данные структуры. В предыдущем сценарии Службы Google Play — это экосистема, выступающая в роли доверенного корневого центра сертификации (ЦС). Когда вы вводите устройства в локальную фабрику Android, каждое устройство включает один и тот же набор учетных данных фабрики и один и тот же набор ЦС.

Индивидуальные услуги по вводу в эксплуатацию

Для ввода в эксплуатацию Local Android Fabric мы использовали параметры по умолчанию для создания CommissioningRequest в API-интерфейсе CommissioningClient:

val request: CommissioningRequest = CommissioningRequest.builder().build()

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

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

class CommissioningRequest {
  static CommissioningRequest.Builder builder();

  class Builder {
    Builder setCommissioningService(@Nullable ComponentName commissioningService);

    CommissioningRequest build();
  }
}

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

Шаг 1. Создайте средство запуска GPS-активности

Во-первых, давайте создадим средство запуска действий для обработки IntentSender из API CommissioningClient.

  1. Откройте HomeFragment в папке java/screens/home/ .
  2. Замените комментарий // CODELAB: commissionDeviceLauncher declaration следующим объявлением:
    // The ActivityResult launcher that launches the "commissionDevice" activity in Google Play
    // Services.
    private lateinit var commissionDeviceLauncher: ActivityResultLauncher<IntentSenderRequest>
    
  3. Замените комментарий // CODELAB: commissionDeviceLauncher definition следующим кодом, чтобы зарегистрировать и обработать результат действия по вводу в эксплуатацию:
    commissionDeviceLauncher =
        registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result ->
          // Commission Device Step 5.
          // The Commission Device activity in GPS has completed.
          val resultCode = result.resultCode
          if (resultCode == Activity.RESULT_OK) {
            Timber.d("CommissionDevice: Success")
            // We now need to capture the device information for the app's fabric.
            // Once this completes, a call is made to the viewModel to persist the information
            // about that device in the app.
            showNewDeviceAlertDialog(result)
          } else {
            viewModel.commissionDeviceFailed(resultCode)
          }
        }    ```
    
    

Шаг 2: Создайте объекты LiveData

Обратный вызов успеха API .commissionDevice() предоставляет IntentSender , который будет использоваться для запуска Действия устройства с комиссией в Сервисах Google Play. В HomeViewModel мы создадим два объекта LiveData для отчета о результате этого вызова API:

  • commissionDeviceStatus для отслеживания TaskStatus .
  • commissionDeviceIntentSender для обработки результата вызова .commissionDevice() . Этот объект LiveData запустит только что созданный ActivityLauncher и отобразит пользователю активность GPS-комиссии.
  1. В private fun setupObservers() замените комментарий // CODELAB: commissionDeviceStatus следующим наблюдателем:
    // The current status of the share device action.
    viewModel.commissionDeviceStatus.observe(viewLifecycleOwner) { status ->
      Timber.d("commissionDeviceStatus.observe: status [${status}]")
    }
    
  2. Затем замените комментарий // CODELAB: commissionDeviceIntentSender следующим наблюдателем:
    viewModel.commissionDeviceIntentSender.observe(viewLifecycleOwner) { sender ->
      Timber.d(
          "commissionDeviceIntentSender.observe is called with [${intentSenderToString(sender)}]")
      if (sender != null) {
        // Commission Device Step 4: Launch the activity described in the IntentSender that
        // was returned in Step 3 (where the viewModel calls the GPS API to commission
        // the device).
        Timber.d("CommissionDevice: Launch GPS activity to commission device")
        commissionDeviceLauncher.launch(IntentSenderRequest.Builder(sender).build())
        viewModel.consumeCommissionDeviceIntentSender()
      }
    }
    

Шаг 3. Вызов API

Теперь, когда мы написали код для обработки потока API, пришло время вызвать API, передать пользовательскую службу (которую мы определим на следующем шаге) и опубликовать в наших объектах LiveData.

  1. Откройте HomeViewModel.kt в папке java/screens/home/ .
  2. Замените комментарий // CODELAB: commissionDevice на следующий commissionDeviceRequest . setCommissioningService связывает AppCommissioningService с экземпляром CommissioningService , возвращаемым функцией обратного вызова. Когда вы передаете настраиваемую службу, Home Mobile SDK сначала вводит устройства в структуру Google, а затем отправляет полезные данные обратно в AppCommissioningService .
    fun commissionDevice(context: Context) {
      _commissionDeviceStatus.postValue(TaskStatus.InProgress)
    
      val commissionDeviceRequest =
          CommissioningRequest.builder()
              .setCommissioningService(ComponentName(context, AppCommissioningService::class.java))
              .build()
    
  3. Вызовите .getCommissioningClient() , затем вызовите .commissionDevice() .
    Matter.getCommissioningClient(context)
        .commissionDevice(commissionDeviceRequest)
    

Чтобы завершить нашу функцию commissionDevice , добавьте addOnSuccessListener и addOnFailureListener и опубликуйте в объектах LiveData:

      .addOnSuccessListener { result ->
        // Communication with fragment is via livedata
        _commissionDeviceIntentSender.postValue(result)
      }
      .addOnFailureListener { error ->
        Timber.e(error)
        _commissionDeviceStatus.postValue(
          TaskStatus.Failed("Failed to to get the IntentSender.", error)
      }
}

После использования отправителя следует вызвать consumeCommissionDeviceIntentSender() , чтобы избежать повторного получения отправителя после изменения конфигурации.

  /**
   * Consumes the value in [_commissionDeviceIntentSender] and sets it back to null. Needs to be
   * called to avoid re-processing the IntentSender after a configuration change (where the LiveData
   * is re-posted).
   */
  fun consumeCommissionDeviceIntentSender() {
    _commissionDeviceIntentSender.postValue(null)
  }

5. Создайте службу ввода в эксплуатацию

В функции commissionDevice() мы запросили получение CommissioningService из CommissioningClient API. В этом потоке API CommissioningClient сначала вводит устройства в локальную структуру Android, а затем возвращает обратный вызов, который включает объект CommissioningRequestMetadata :

public interface CommissioningService {
interface Callback {
    void onCommissioningRequested(CommissioningRequestMetadata metadata);
  }
}

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

class MatterCommissioningService : Service(), CommissioningService.Callback {
   private val commissioningServiceDelegate =
     CommissioningService.Builder(this)
       .setCallback(this)
       .build()

   override fun onBind(intent: Intent) = commissioningServiceDelegate.asBinder()

   override fun onCommissioningRequested(metadata: CommissioningRequestMetadata) {
     // perform commissioning

     commissioningServiceDelegate
       .sendCommissioningComplete(CommissioningCompleteMetadata.builder().build())
   }
 }

Шаг 1. Ознакомьтесь с настраиваемой службой AppCommissioningService.

Чтобы помочь вам приступить к работе, мы уже определили базовую структуру класса для нашей пользовательской службы ввода в эксплуатацию. Вот краткий обзор функциональности сервиса. Чтобы продолжить, откройте AppCommissioningService в java/commissioning .

Мы добавили следующие импорты для API Home Mobile SDK:

import com.google.android.gms.home.matter.commissioning.CommissioningCompleteMetadata
import com.google.android.gms.home.matter.commissioning.CommissioningRequestMetadata
import com.google.android.gms.home.matter.commissioning.CommissioningService

AppCommissioningService также включает библиотеки из репозитория Matter ( connectedhomeip ) :

import com.google.home_sample_app_for_matter.chip.ChipClient

Наконец, сервис включает импорт для поддержки сопрограмм Hilt и Kotlin .

Затем мы создаем конструктор и настраиваем несколько вещей, в том числе commissioningServiceDelegate , который мы будем использовать, чтобы сообщить службам Google Play о завершении ввода в эксплуатацию.

private lateinit var commissioningServiceDelegate: CommissioningService
...
commissioningServiceDelegate = CommissioningService.Builder(this).setCallback(this).build()

Теперь пришло время добавить функции ввода в эксплуатацию.

Шаг 2. Переопределение onCommissioningRequested

Чтобы ввести устройства в среду разработки приложения, выполните следующие действия:

  1. Откройте AppCommissioningService в java/commissioning .
  2. Найдите функцию onCommissioningRequested() . Мы предоставили сообщение журнала, которое распечатывает CommissioningRequestMetadata . Замените комментарий // CODELAB: onCommissioningRequested() , чтобы запустить сопрограмму serviceScope и получить deviceId .
    // Perform commissioning on custom fabric for the sample app.
    serviceScope.launch {
      val deviceId = devicesRepository.incrementAndReturnLastDeviceId()
    
  3. Выполните ввод в эксплуатацию. Для этого шага мы можем передать информацию об устройстве, возвращенную в объекте CommissioningRequestMetadata . ChipClient использует эту информацию метаданных для создания безопасного канала между приложением GHSA for Matter и вашим устройством.
    Timber.d("Commissioning: App fabric -> ChipClient.establishPaseConnection(): deviceId [${deviceId}]")
    chipClient.awaitEstablishPaseConnection(
        deviceId,
        metadata.networkLocation.ipAddress.hostAddress!!,
        metadata.networkLocation.port,
        metadata.passcode)
    Timber.d("Commissioning: App fabric -> ChipClient.commissionDevice(): deviceId [${deviceId}]")
    chipClient.awaitCommissionDevice(deviceId, null)
    
  4. Используйте commissioningServiceDelegate , чтобы сообщить сервисам Google Play о завершении ввода в эксплуатацию. В .sendCommissioningComplete() передайте CommissioningCompleteMetadata .
      Timber.d("Commissioning: Calling commissioningServiceDelegate.sendCommissioningComplete()")
      commissioningServiceDelegate
          .sendCommissioningComplete(
              CommissioningCompleteMetadata.builder().setToken(deviceId.toString()).build())
          .addOnSuccessListener {
              Timber.d("Commissioning: OnSuccess for commissioningServiceDelegate.sendCommissioningComplete()")
          }
          .addOnFailureListener { ex -> 
            Timber.e(ex, "Commissioning: Failed to send commissioning complete.", ex)
          }
    }
    

Запустите приложение

Теперь, когда весь код, необходимый для ввода в эксплуатацию в нашей локальной сети, готов, пришло время его протестировать. Выберите свое устройство Android и запустите приложение. На главном экране нажмите «Добавить устройство» и выполните действия, необходимые для ввода устройства в эксплуатацию.

По завершении ввода в эксплуатацию ваше устройство теперь участвует в двух структурах: локальной структуре Android и вашей локальной структуре разработки. Каждая структура имеет собственный набор учетных данных и уникальный 64-битный идентификатор структуры.

6. Устройства управления

Ввод в эксплуатацию среды разработки позволяет использовать библиотеки из репозитория Matter ( connectedhomeip ) для управления устройствами из примера приложения.

Мы создали несколько вспомогательных классов, чтобы упростить доступ к кластерам устройств и отправку команд. Чтобы узнать больше, откройте ClustersHelper в java/clusters . Этот помощник Singleton импортирует следующие библиотеки для доступа к информации об устройстве:

import chip.devicecontroller.ChipClusters
import chip.devicecontroller.ChipStructs

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

suspend fun toggleDeviceStateOnOffCluster(deviceId: Long, endpoint: Int) {
  Timber.d("toggleDeviceStateOnOffCluster())")
  val connectedDevicePtr =
      try {
        chipClient.getConnectedDevicePointer(deviceId)
      } catch (e: IllegalStateException) {
        Timber.e("Can't get connectedDevicePointer.")
        return
      }
  return suspendCoroutine { continuation ->
    getOnOffClusterForDevice(connectedDevicePtr, endpoint)
        .toggle(
            object : ChipClusters.DefaultClusterCallback {
              override fun onSuccess() {
                continuation.resume(Unit)
              }
              override fun onError(ex: Exception) {
                Timber.e("readOnOffAttribute command failure: $ex")
                continuation.resumeWithException(ex)
              }
            })
  }
}

Переключить устройство

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

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

На устройстве пакеты проверяются, расшифровываются, а затем отправляются с обратным вызовом. Функции обратного вызова включают EndpointId, ClusterId и AttributeId, доступные из attributePath . Например, этот код можно реализовать на устройстве Matter:

void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t mask, uint8_t type,
                                       uint16_t size, uint8_t * value)
{
    // handle callback
    ClusterId clusterId     = attributePath.mClusterId;
    AttributeId attributeId = attributePath.mAttributeId;
}

На следующих шагах вы будете использовать Matter SDK и ClustersHelper для переключения устройства.

  1. Перейдите в DeviceViewModel в java/screens/device .
  2. Найдите функцию updateDeviceStateOn .
  3. Замените комментарий // CODELAB: toggle кодом для вызова clustersHelper , затем обновите репозиторий устройства:
    Timber.d("Handling real device")
        try {
          clustersHelper.setOnOffDeviceStateOnOffCluster(deviceUiModel.device.deviceId, isOn, 1)
          devicesStateRepository.updateDeviceState(deviceUiModel.device.deviceId, true, isOn)
        } catch (e: Throwable) {
          Timber.e("Failed setting on/off state")
        }
    

Эта функция вызывается из DeviceFragment :

// Change the on/off state of the device
binding.onoffSwitch.setOnClickListener {
  val isOn = binding.onoffSwitch.isChecked
  viewModel.updateDeviceStateOn(selectedDeviceViewModel.selectedDeviceLiveData.value!!, isOn)
}

Запустите приложение

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

7. Делитесь устройствами с другими экосистемами

Совместное использование устройства в спецификации Matter называется потоком с несколькими администраторами .

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

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

Home Mobile SDK предоставляет эту функциональность в API ShareDeviceRequest , что позволяет:

  1. Откройте временное окно ввода в эксплуатацию для устройств.
  2. Измените состояние своих устройств, разрешив их ввод в эксплуатацию на другой фабрике.
  3. Управляйте своими устройствами из других приложений и экосистем.

На следующих шагах вы будете использовать Home Mobile SDK для совместного использования устройств.

Шаг 1. Создайте средство запуска GPS-активности

Подобно средству запуска действий по вводу в эксплуатацию, которое мы создали при вводе в эксплуатацию структуры разработки, мы создали средство запуска действий общего устройства для обработки IntentSender из API-интерфейса CommissioningClient.

  1. Откройте DeviceFragment в папке java/screens/device/ .
  2. Замените // CODELAB: shareDeviceLauncher definition следующим кодом для регистрации и обработки результата действия .shareDevice() :
    shareDeviceLauncher =
        registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result ->
          // Share Device Step 5.
          // The Share Device activity in GPS (step 4) has completed.
          val resultCode = result.resultCode
          if (resultCode == RESULT_OK) {
            Timber.d("ShareDevice: Success")
            viewModel.shareDeviceSucceeded(selectedDeviceViewModel.selectedDeviceLiveData.value!!)
          } else {
            viewModel.shareDeviceFailed(
                selectedDeviceViewModel.selectedDeviceLiveData.value!!, resultCode)
          }
        }
    

Шаг 2. Просмотрите объекты LiveData

Обратный вызов успеха API .shareDevice() предоставляет IntentSender , который будет использоваться для запуска операции совместного использования устройства в сервисах Google Play. В DeviceViewModel мы создали два объекта LiveData для отчета о результате этого вызова API:

  • _shareDeviceStatus для отслеживания TaskStatus .
    // The current status of the share device action.
    viewModel.shareDeviceStatus.observe(viewLifecycleOwner) { status ->
      val isButtonEnabled = status !is InProgress
      updateShareDeviceButton(isButtonEnabled)
      if (status is TaskStatus.Failed) {
        showAlertDialog(errorAlertDialog, status.message, status.cause!!.toString())
      }
    }
    
  • _shareDeviceIntentSender для обработки результата вызова .sharedevice() .

viewModel.shareDeviceIntentSender.observe(viewLifecycleOwner) { sender -> Timber.d("shareDeviceIntentSender.observe вызывается с [${intentSenderToString(sender)}]") if (sender != null) { // Общий доступ к устройству Шаг 4: Запуск действие, описанное в IntentSender, которое // было возвращено на шаге 3 (где viewModel вызывает GPS API для ввода в эксплуатацию // устройства). Timber.d("ShareDevice: запуск действия GPS для совместного использования устройства") shareDeviceLauncher.launch(IntentSenderRequest.Builder(sender).build()) viewModel.consumeShareDeviceIntentSender() } } ```

На следующих шагах мы будем использовать эти объекты LiveData в вызове API .shareDevice() .

Шаг 3. Вызов API

Теперь пришло время инициировать задачу совместного использования устройства.

  1. Откройте DeviceViewModel.kt в папке java/screens/device/ .
  2. Найдите функцию shareDevice() . Замените комментарий // CODELAB: shareDevice на ShareDeviceRequest . DeviceDescriptor предоставляет конкретную информацию об устройстве, такую ​​как его идентификатор поставщика, идентификатор продукта и тип устройства. В этом примере мы жестко закодировали значения.
      Timber.d("ShareDevice: Setting up the IntentSender")
      val shareDeviceRequest =
          ShareDeviceRequest.builder()
              .setDeviceDescriptor(DeviceDescriptor.builder().build())
              .setDeviceName("temp device name")
    
  3. Установите окно ввода в эксплуатацию и параметры . В этот момент на устройстве открыто окно временного ввода в эксплуатацию.
              .setCommissioningWindow(
                  CommissioningWindow.builder()
                      .setDiscriminator(Discriminator.forLongValue(DISCRIMINATOR))
                      .setPasscode(SETUP_PIN_CODE)
                      .setWindowOpenMillis(SystemClock.elapsedRealtime())
                      .setDurationSeconds(OPEN_COMMISSIONING_WINDOW_DURATION_SECONDS.toLong())
                      .build())
              .build()
    
  4. Вызовите .getCommissioningClient() , только на этот раз используйте API .shareDevice() . Успешный обратный вызов API- commissioningClient.shareDevice() предоставляет IntentSender, который будет использоваться для запуска операции «Общий доступ к устройству» в сервисах Google Play.
    Matter.getCommissioningClient(activity)
        .shareDevice(shareDeviceRequest)
    
  5. Чтобы завершить нашу функцию shareDevice , добавьте addOnSuccessListener и addOnFailureListener и опубликуйте в объектах LiveData:
          .addOnSuccessListener { result ->
            Timber.d("ShareDevice: Success getting the IntentSender: result [${result}]")
            // Communication with fragment is via livedata
            _backgroundWorkAlertDialogAction.postValue(BackgroundWorkAlertDialogAction.Hide)
            _shareDeviceIntentSender.postValue(result)
          }
          .addOnFailureListener { error ->
            Timber.e(error)
            _backgroundWorkAlertDialogAction.postValue(BackgroundWorkAlertDialogAction.Hide)
            _shareDeviceStatus.postValue(
                TaskStatus.Failed("Setting up the IntentSender failed", error))
          }
    

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

  /**
   * Consumes the value in [_shareDeviceIntentSender] and sets it back to null. Needs to be called
   * to avoid re-processing an IntentSender after a configuration change where the LiveData is
   * re-posted.
   */
  fun consumeShareDeviceIntentSender() {
    _shareDeviceIntentSender.postValue(null)
  }

Запустите приложение

Чтобы поделиться своим устройством Matter с другими экосистемами, на вашем устройстве Android должна быть установлена ​​другая платформа. Мы создали еще один экземпляр примера приложения, который вы можете использовать в качестве целевого уполномоченного.

После того, как вы установили целевого комиссара на свое устройство Android, убедитесь, что вы можете поделиться своим устройством Matter. Приложение целевого уполномоченного помечено как GHSAFM-TC .

Теперь ваши устройства могут участвовать в трех структурах:

  1. Локальная структура Android.
  2. Ваша структура разработки (это приложение).
  3. Это третья структура, с которой вы только что предоставили общий доступ к устройству.

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

Поздравления

Поздравляем, вы успешно завершили этот курс Codelab и узнали, как вводить устройства в эксплуатацию и совместно использовать их с помощью Home Mobile SDK.

Если у вас возникли проблемы с примером приложения, попробуйте выполнить шаги для проверки среды:

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

Чтобы получить официальное руководство от Google по техническим вопросам, используйте Форум разработчиков умного дома:

Чтобы получить техническую поддержку от сообщества, используйте тег google-smart-home на Stack Overflow: