Cómo inicializar la casa en Android

Antes de usar cualquiera de las APIs de Home para Android, debes inicializar la casa en tu app. En este paso, crearás una instancia singleton de Home para el contexto local.

Solo debe haber una instancia de Home activa a la vez.

Este es el punto de entrada a las APIs de Home y también implica declarar qué rasgos y tipos de dispositivos planeas usar con las APIs de Device & Structure y Automation. Si recién comienzas a usar el ecosistema de Google Home y no sabes qué rasgos o tipos de dispositivos registrar, te sugerimos algunos de los más comunes en esta guía.

Crea una instancia de Home

Para comenzar, importa estos paquetes a tu app:

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

Para inicializar las APIs de Home, haz lo siguiente:

  1. Obtén una referencia al contexto de Application. Este contexto no depende de ningún ciclo de vida de la actividad y existirá mientras tu app esté activa. Puedes obtenerlo llamando a getApplicationContext() dentro de un Activity o Service:

    val context = getApplicationContext()
    
  2. Crea una instancia de FactoryRegistry con todos los rasgos y tipos de dispositivos que planeas usar en tu app.

    En esta guía, sugerimos algunos comunes (tipos de dispositivos de luz, enchufe, sensor, interruptor y termostato, y rasgos de presencia y Asistente para automatizaciones), en caso de que no sepas qué necesitas. Para obtener más información, consulta Registro de rasgos y tipos de dispositivos.

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

    Se requieren instrucciones de importación para cada rasgo y tipo de dispositivo individuales registrados aquí (Android Studio debería solicitarte que los agregues).

  3. Crea una instancia de HomeConfig con el contexto de la corrutina Dispatchers.IO y tu instancia de registro.

    val homeConfig = HomeConfig(
            coroutineContext = Dispatchers.IO,
            factoryRegistry = registry)
    
  4. Por último, crea la instancia singleton de Home, que es el punto de entrada a las APIs, con el contexto y el HomeConfig.

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

Para evitar errores con sesiones no válidas, es importante que solo se cree una instancia singleton de Home, para lo cual se debe encapsular en una declaración de objeto.

Por ejemplo, la app de ejemplo lo hace de la siguiente manera:

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

Acceso con Google iniciado por la app

Es posible que desees administrar las autenticaciones de Google de tus usuarios dentro de tu app. Esto te permite usar la misma cuenta de usuario en varios servicios de Google, como Google Home, Drive, Maps, etcétera.

Con el acceso con Google iniciado por la app, puedes obtener una instancia de HomeClient vinculada de forma explícita a un usuario en particular, lo que permite omitir el selector de Cuentas de Google y la pantalla de consentimiento cuando la cuenta ya está autorizada.

Además, este enfoque evita que los usuarios vean dos pantallas diferentes de selección de cuentas: una del acceso de la app y otra de Google Home.

Para ello, sigue los mismos pasos que se describen en Crea una instancia de Home, pero, en lugar de llamar a Home.getClient(context, homeConfig) en el paso 4, llama a Home.getClient(context, userAccount, homeConfig), donde el segundo parámetro es un Lazy<UserAccount>. Esto devuelve una instancia de HomeClientWithProvidedAccount, una subclase de HomeClient, que está vinculada de forma explícita a la Cuenta de Google especificada:

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()
     )

Si el usuario especificado no está autorizado, pídele permiso llamando a los siguientes métodos en la instancia de HomeClientWithProvidedAccount:

  1. registerActivityResultCallerForPermissions() con una referencia al ActivityResultCaller que deseas usar.
  2. requestPermissions(). Aparecerá la pantalla de consentimiento de GHP, en la que el usuario puede otorgar su permiso.

Puedes crear un HomeClient con un UserAccount y, luego, llamar a requestPermissions() con forceLaunch==true para volver a iniciar la pantalla de consentimiento y permitir que el usuario actualice el otorgamiento de permisos:

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

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

Consulta la API de Permissions para obtener más información sobre cómo administrar los permisos de las APIs de Home.

Registro de características y tipos de dispositivos

La clase FactoryRegistry ayuda a los desarrolladores a optimizar el tamaño del archivo binario de su app, ya que les permite indicar explícitamente qué rasgos y tipos de dispositivos usa su app.

Ten en cuenta que los permisos y el registro de fábrica están desacoplados. Por lo tanto, no se puede acceder a los tipos y rasgos no registrados que están disponibles para tu app a través de permisos, pero que no se incluyen en el registro de fábrica, con la API de Automation, ni se devuelven en las llamadas a los métodos traits() o types() masivos.