Prima di utilizzare una qualsiasi delle API Home per Android, devi inizializzare la casa nella tua app. In questo passaggio, creerai un'istanza singleton di
Home per il contesto locale.
Solo un'istanza di Home deve essere attiva alla volta.
Questo è il punto di accesso alle API Home e comporta anche la dichiarazione dei tratti e dei tipi di dispositivi che intendi utilizzare con le API Device &Structure e Automation. Se hai appena iniziato a utilizzare l'ecosistema Google Home e non sai quali tratti o tipi di dispositivi registrare, in questa guida abbiamo suggerito alcuni dei più comuni.
Creare un'istanza di Home
Per iniziare, importa questi pacchetti nella tua app:
import android.content.Context
import com.google.home.FactoryRegistry
import com.google.home.HomeConfig
import com.google.home.Home
Per inizializzare le API Home:
Ottieni un riferimento al
Applicationcontesto. Questo contesto non dipende dal ciclo di vita dell'attività e rimarrà attivo finché la tua app è attiva. Puoi ottenerlo chiamandogetApplicationContext()all'interno di un'Activityo di unService:val context = getApplicationContext()Crea un'istanza di
FactoryRegistrycon tutti i tratti e i tipi di dispositivi che intendi utilizzare nella tua app.Per questa guida, abbiamo suggerito alcuni tipi comuni (tipi di dispositivi Light, Plug, Sensor, Switch e Thermostat, tratti presence e Assistant per le automazioni), nel caso in cui non sai di cosa hai bisogno. Per saperne di più, consulta Registrazione di tratti e tipi di dispositivi.
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))Sono necessarie le istruzioni di importazione per ogni singolo tratto e tipo di dispositivo registrato qui (Android Studio dovrebbe chiederti di aggiungerle).
Crea un'istanza di
HomeConfigutilizzando ilDispatchers.IOcontesto della coroutine e l'istanza del registro.val homeConfig = HomeConfig( coroutineContext = Dispatchers.IO, factoryRegistry = registry)Infine, crea l'istanza singleton di
Home, che è il punto di accesso a lle API, utilizzando il contesto eHomeConfig.val homeManager: HomeClient = Home.getClient(context, homeConfig)
Per evitare errori con sessioni non valide, è importante creare solo un'istanza singleton
di Home racchiudendola in una dichiarazione di oggetto.
Ad esempio, l'app di esempio lo fa in questo modo:
internal object HomeClientModule {
@Provides
@Singleton
fun provideHomeClient(@ApplicationContext context: Context): HomeClient {
return Home.getClient(
context,
HomeConfig(
coroutineContext = IODispatcherModule.provideIoDispatcher(),
factoryRegistry = registry,
),
)
}
}
Accesso a Google avviato dall'app
Potresti voler gestire le autenticazioni Google dei tuoi utenti all'interno della tua app. In questo modo, puoi utilizzare lo stesso account utente su vari servizi Google come Google Home, Drive, Maps e così via.
Con l'accesso a Google avviato dall'app, puoi ottenere un'istanza di HomeClient collegata esplicitamente a un determinato utente, bypassando così il selettore dell'Account Google e la schermata per il consenso quando l'account è già autorizzato.
Inoltre, questo approccio impedisce agli utenti di visualizzare due schermate di selezione dell'account diverse: una dall'accesso dell'app e una da Google Home.
Per farlo, devi fare riferimento ad Autenticare gli utenti con Accedi con Google e completare i seguenti passaggi:
Creare un ID client dell'applicazione web OAuth
- Apri la console Google Cloud.
- Vai alla pagina Credenziali della console Google Cloud.
- Seleziona un progetto esistente o creane uno nuovo.
- Configura la schermata per il consenso OAuth (se non l'hai già fatto).
- Prima di creare le credenziali, assicurati che la schermata per il consenso OAuth sia configurata con i dettagli della tua app, inclusi gli URL delle norme sulla privacy e dei Termini di servizio.
- Crea un ID client OAuth (tipo Applicazione web).
- Nella pagina Credenziali, fai clic su
+ CREATE CREDENTIALSe seleziona ID client OAuth dal menu a discesa. - Per Tipo di applicazione, seleziona Applicazione web.
- Inserisci un nome per il client web (ad es. "Backend web della mia app").
- Fai clic su Crea.
- Nella pagina Credenziali, fai clic su
- Recupera l'ID client.
- Una volta creata, la console visualizzerà il nuovo ID client. Questo è il valore che utilizzerai nella tua app per Android (ad es. "{project number}-.....apps.googleusercontent.com")
- Ti consigliamo di archiviare l'ID client esternamente (ad es.in
build.gradle) anziché codificarlo direttamente.
Creare un'istanza di una richiesta di Accedi con Google
Utilizza l'ID dell'app web per creare una richiesta di accesso a 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()
Creare il flusso di accesso con Google
Per implementare il flusso di accesso, utilizza CredentialManager per eseguire una richiesta Sign in with Google. Una volta che l'utente seleziona un account, estrai il suo indirizzo email dal token ID Google risultante per creare un android.accounts.Account. Questo account viene quindi utilizzato per inizializzare un'istanza di HomeClient collegata specificamente all'utente che ha eseguito l'accesso.
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)
}
Ottenere una nuova istanza di HomeClient
Segui gli stessi passaggi descritti in
Creare un'istanza di Home, ma anziché chiamare
Home.getClient(context, homeConfig) al passaggio 4, chiama
Home.getClient(context, userAccount,
homeConfig),
dove il secondo parametro è un Lazy<UserAccount>. Viene restituita un'istanza di
HomeClientWithProvidedAccount,
una sottoclasse di HomeClient, collegata esplicitamente all'Account Google
specificato:
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()
)
Se l'utente specificato non è autorizzato, chiedi all'utente l'autorizzazione chiamando i seguenti metodi sulleistanza:HomeClientWithProvidedAccount
registerActivityResultCallerForPermissions()con un riferimento all'ActivityResultCaller che vuoi utilizzare.requestPermissions(). Viene visualizzata la schermata per il consenso GHP, in cui l'utente può concedere l'autorizzazione.
Puoi creare un HomeClient con un
UserAccount e poi chiamare
requestPermissions() con forceLaunch==true per avviare di nuovo la schermata per il consenso
e consentire all'utente di aggiornare la concessione delle autorizzazioni:
val client =
Home.getClient(
context = context.applicationContext,
account =
lazy {
UserAccount.GoogleAccount(androidAccount)
},
homeConfig = HomeConfig()
)
client.registerActivityResultCallerForPermissions(this)
client.requestPermissions(forceLaunch= true)
Per ulteriori informazioni sulla gestione delle autorizzazioni delle API Home, consulta API Permissions.
Aggiornare l'intera attività con il nuovo HomeClient
Una volta che hai una nuova istanza di HomeClient, devi aggiornare l'intera attività per riabbonarti e recuperare le strutture, i dispositivi e altri dati pertinenti completi associati a questo account utente.
Registrazione di tratti e tipi di dispositivi
La classe FactoryRegistry aiuta gli sviluppatori a ottimizzare le dimensioni del file binario dell'app consentendo loro di indicare esplicitamente quali tratti e tipi di dispositivi vengono utilizzati dalla loro app.
Tieni presente che le autorizzazioni e il registro di fabbrica sono disaccoppiati. Pertanto,
i tratti e i tipi non registrati disponibili per la tua app tramite le autorizzazioni,
ma non inclusi nel registro di fabbrica, non sono accessibili tramite l'API
Automation né vengono restituiti nelle chiamate di metodi collettive
traits() o types().