Инициализировать дом на Android

Прежде чем использовать какие-либо API Home для Android, необходимо инициализировать Home в вашем приложении. На этом шаге вы создадите единственный экземпляр Home для локального контекста.

В любой момент времени должен быть активен только один экземпляр Home .

Это точка входа в API Home, а также указание характеристик и типов устройств, которые вы планируете использовать с API Device & Structure и Automation. Если вы только начинаете работать с экосистемой Google Home и не уверены, какие характеристики или типы устройств нужно зарегистрировать, в этом руководстве мы предложили несколько наиболее распространенных вариантов.

Создайте экземпляр Home.

Для начала импортируйте следующие пакеты в ваше приложение:

import android.content.Context
import com.google.home.FactoryRegistry
import com.google.home.HomeConfig
import com.google.home.Home

Для инициализации API Home:

  1. Получите ссылку на контекст Application . Этот контекст не зависит от жизненного цикла какой-либо активности и будет существовать до тех пор, пока ваше приложение работает. Вы можете получить его, вызвав getApplicationContext() внутри Activity или Service :

    val context = getApplicationContext()
    
  2. Создайте экземпляр FactoryRegistry со всеми характеристиками и типами устройств, которые вы планируете использовать в своем приложении.

    В этом руководстве мы предложили несколько распространенных типов устройств (светильник, розетка, датчик, выключатель и термостат, а также характеристики присутствия и данные голосового помощника для автоматизации), на случай, если вы не уверены, что именно вам нужно. Для получения дополнительной информации см. раздел «Регистрация характеристик и типов устройств» .

    val registry = FactoryRegistry(
      traits = listOf(
                AirQuality,
                AreaAttendanceState,
                AreaPresenceState,
                AssistantBroadcast,
                AssistantFulfillment,
                BooleanState,
                ColorControl,
                ExtendedColorControl,
                FlowMeasurement,
                IlluminanceMeasurement,
                LevelControl,
                Notification,
                OccupancySensing,
                OnOff,
                RelativeHumidityMeasurement,
                Switch,
                TemperatureMeasurement,
                Thermostat),
      types = listOf(
                AirQualitySensorDevice,
                ColorDimmerSwitchDevice,
                ColorTemperatureLightDevice,
                ContactSensorDevice,
                DimmableLightDevice,
                DimmablePlugInUnitDevice,
                DimmerSwitchDevice,
                ExtendedColorLightDevice,
                FlowSensorDevice,
                GenericSwitchDevice,
                HumiditySensorDevice,
                LightSensorDevice,
                OccupancySensorDevice,
                OnOffLightDevice,
                OnOffLightSwitchDevice,
                OnOffPluginUnitDevice,
                OnOffSensorDevice,
                SpeakerDevice,
                TemperatureSensorDevice,
                ThermostatDevice))
    

    Для каждого отдельного признака и типа устройства, зарегистрированных здесь, необходимы операторы импорта ( Android Studio предложит вам добавить их).

  3. Создайте экземпляр HomeConfig , используя контекст сопрограммы Dispatchers.IO и ваш экземпляр реестра.

    val homeConfig = HomeConfig(
            coroutineContext = Dispatchers.IO,
            factoryRegistry = registry)
    
  4. Наконец, создайте единственный экземпляр класса Home , который является точкой входа в API, используя контекст и HomeConfig .

    val homeManager: HomeClient = Home.getClient(context, homeConfig)
    

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

Например, в демонстрационном приложении это делается следующим образом:

internal object HomeClientModule {
  @Provides
  @Singleton
  fun provideHomeClient(@ApplicationContext context: Context): HomeClient {
    return Home.getClient(
      context,
      HomeConfig(
        coroutineContext = IODispatcherModule.provideIoDispatcher(),
        factoryRegistry = registry,
      ),
    )
  }
}

Вход в систему Google, инициированный приложением.

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

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

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

Для этого выполните те же шаги, что и при создании экземпляра Home , но вместо вызова Home.getClient(context, homeConfig) на шаге 4 вызовите Home.getClient(context, userAccount, homeConfig) , где вторым параметром является Lazy<UserAccount> . Это вернет экземпляр HomeClientWithProvidedAccount , подкласса HomeClient , явно привязанного к указанной учетной записи Google:

val client =
     Home.getClient(
       context = context.applicationContext,
       account =
         lazy {
         // 1. Create the Account object.
           val androidAccount = Account(userEmail,
                                        GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE)
         // 2. Wrap it in UserAccount.GoogleAccount.
           UserAccount.GoogleAccount(androidAccount)
         },
       homeConfig = HomeConfig()
     )

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

  1. При вызове registerActivityResultCallerForPermissions() укажите ссылку на ActivityResultCaller , который вы хотите использовать.
  2. Вызов requestPermissions() открывает экран согласия GHP, где пользователь может предоставить свои разрешения.

Вы можете создать HomeClient с UserAccount , а затем вызвать requestPermissions() с forceLaunch==true чтобы снова запустить экран согласия и позволить пользователю обновить предоставленные ему разрешения:

val client =
     Home.getClient(
       context = context.applicationContext,
       account =
         lazy {
              UserAccount.GoogleAccount(androidAccount)
         },
       homeConfig = HomeConfig()
     )

client.registerActivityResultCallerForPermissions(this)
client.requestPermissions(forceLaunch= true)

Дополнительную информацию об управлении разрешениями API Home см. в разделе «API разрешений» .

Регистрация характеристик и типов устройств

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

Обратите внимание, что разрешения и реестр фабрик не связаны между собой. Поэтому незарегистрированные трейты и типы, доступные вашему приложению с помощью разрешений, но не включенные в реестр фабрик, недоступны с помощью API автоматизации и не возвращаются в вызовах методов bulk traits() или types() .