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 estar activa una instancia de Home a la vez.
Este es el punto de entrada a las APIs de Home y también implica declarar qué atributos y tipos de dispositivos deseas usar con las APIs de Device &Structure y Automation. Si recién comienzas a usar el ecosistema de Google Home y no estás seguro de qué atributos 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:
Obtén una referencia al
Applicationcontexto. Este contexto no depende de ningún ciclo de vida de la actividad y permanecerá activo mientras tu app esté activa. Puedes obtenerlo llamando agetApplicationContext()dentro de unaActivityoService:val context = getApplicationContext()Crea una
FactoryRegistryinstancia con todos los atributos y tipos de dispositivos que deseas usar en tu app.En esta guía, sugerimos algunos comunes (tipos de dispositivos Light, Plug, Sensor, Switch y Thermostat, y atributos de presencia y Asistente para automatizaciones), en caso de que no sepas lo que necesitas. Para obtener más información, consulta Registro de atributos 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 atributo y tipo de dispositivo individual registrado aquí (Android Studio debería solicitarte que los agregues).
Crea una instancia de
HomeConfigcon elDispatchers.IOcontexto de la corrutina y tu instancia de registro.val homeConfig = HomeConfig( coroutineContext = Dispatchers.IO, factoryRegistry = registry)Por último, crea la instancia singleton de
Home, que es el punto de entrada a las APIs, con el contexto yHomeConfig.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 debes incluirla en una declaración de objeto.
Por ejemplo, la app de muestra 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. Si lo haces, podrás 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 explícitamente a un usuario en particular, lo que evita 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, debes consultar Autentica usuarios con Acceder con Google y completar los siguientes pasos:
Crea un ID de cliente de aplicación web de OAuth
- Abre la consola de Google Cloud.
- Navega a la página Credenciales de la consola de Google Cloud.
- Selecciona un proyecto existente o crea uno nuevo.
- Configura la pantalla de consentimiento de OAuth (si no lo hiciste).
- Antes de crear credenciales, asegúrate de que la pantalla de consentimiento de OAuth esté configurada con los detalles de tu app, incluidas las URLs de la política de privacidad y las condiciones del servicio.
- Crea un ID de cliente de OAuth (tipo de aplicación web).
- En la página Credenciales, haz clic en
+ CREATE CREDENTIALSy selecciona ID de cliente de OAuth en el menú desplegable. - En Tipo de aplicación, selecciona Aplicación web.
- Ingresa un nombre para tu cliente web (p.ej., "Backend web de mi app").
- Haz clic en Crear.
- En la página Credenciales, haz clic en
- Recupera el ID de cliente.
- Después de la creación, la consola mostrará tu nuevo ID de cliente. Este es el valor que usarás en tu aplicación para Android (p. ej., "{project number}-.....apps.googleusercontent.com").
- Te recomendamos que almacenes el ID de cliente de forma externa (p. ej., en
build.gradle) en lugar de codificarlo directamente.
Crea una instancia de una solicitud de Acceder con Google
Usa el ID de la app web para crear una solicitud de Acceder con Google:
// Your Google Cloud console Web Client ID for Google Sign-In
val serverClientId = BuildConfig.DEFAULT_WEB_CLIENT_ID
// Build the request for Google ID token
val googleIdOption = GetGoogleIdOption.Builder()
.setFilterByAuthorizedAccounts(false) // Show all Google Accounts on the device
.setServerClientId(serverClientId) // embed WebClientID in token
.build()
// Build the GetCredentialRequest
val request = GetCredentialRequest.Builder().addCredentialOption(googleIdOption).build()
Crea el flujo de Acceder con Google
Para implementar el flujo de acceso, usa CredentialManager para ejecutar una solicitud de Sign in with Google. Una vez que el usuario selecciona una cuenta, extrae su correo electrónico del token de ID de Google resultante para crear un android.accounts.Account. Luego, esta cuenta se usa para inicializar una instancia de HomeClient vinculada específicamente a ese usuario que accedió.
try {
// CredentialManager is responsible for interacting with various credential providers on the device
val credentialManager = CredentialManager.create(context)
// Credential returns when user has selected an account and the getCredential call completes
val result = credentialManager.getCredential(context = context, request = request)
val credential = result.credential
if (
credential is CustomCredential &&
credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL
) {
try {
val googleCredential = GoogleIdTokenCredential.createFrom(credential.data)
googleCredential.id.let { userEmail ->
Log.i(TAG, "Email found in Google ID Token: $email")
/*
Why "com.google"?
The string "com.google" is a standard identifier used in Android's android.accounts.
Account system to represent accounts managed by Google. This is often used when
interacting with Android's Account Manager or when using Google-specific APIs. So,
even if the email ends in "@gmail.com", the underlying account type or provider is
still considered "com.google" within the Android system.
*/
val account = Account(userEmail, "com.google")
Log.d(TAG,"Switched account to : $userEmail")
// Get the new Home Client Instance with the userEmail
}
Log.i(TAG, "Account switch complete. Emitting navigation event.")
} catch (e: Exception) {
Log.e(TAG,"Could not convert CustomCredential to Google ID Token", e)
}
}
} catch (e: Exception) {
Log.e(TAG, "Google Sign-In failed with unexpected error", e)
}
Obtén una instancia nueva de HomeClient
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),
en el que el segundo parámetro es un Lazy<UserAccount>. Esto muestra una instancia de
HomeClientWithProvidedAccount,
una subclase de HomeClient, que está vinculada explícitamente 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
HomeClientWithProvidedAccount
instancia:
registerActivityResultCallerForPermissions()con una referencia al ActivityResultCaller que deseas usar.requestPermissions(). Esto muestra 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 su 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.
Actualiza toda la actividad con el nuevo HomeClient
Una vez que tengas una instancia nueva de HomeClient, debes actualizar toda la actividad para volver a suscribirte y recuperar las estructuras, los dispositivos y otros datos pertinentes asociados con esta cuenta de usuario.
Registro de atributos y tipos de dispositivos
La clase FactoryRegistry ayuda a los desarrolladores a optimizar el tamaño binario de su app, ya que les permite indicar explícitamente qué atributos 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,
los atributos y tipos no registrados que están disponibles para tu app con permisos
pero que no están incluidos en el registro de fábrica, no son accesibles con la
API de Automation ni se muestran en las llamadas masivas a los métodos
traits() o types().