Prima di utilizzare una 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.
Deve essere attiva una sola istanza di Home alla volta.
Questo è il punto di accesso alle API Home e comporta anche la dichiarazione di quali tratti e tipi di dispositivi 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 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 contesto
Application. Questo contesto non dipende da alcun ciclo di vita dell'attività e rimarrà attivo finché la tua app è attiva. Puoi ottenerlo chiamandogetApplicationContext()entro leActivityo leService:val context = getApplicationContext()Crea un'istanza
FactoryRegistrycon tutti i tratti e i tipi di dispositivi che intendi utilizzare nella tua app.Per questa guida, abbiamo suggerito alcuni tipi comuni (dispositivi di tipo Luce, Presa, Sensore, Interruttore e Termostato, tratti di presenza e dell'assistente per le automazioni), nel caso in cui non sapessi cosa ti serve. Per saperne di più, vedi 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 richieste le istruzioni di importazione per ogni singola caratteristica e tipo di dispositivo registrato qui (Android Studio dovrebbe chiederti di aggiungerle).
Crea un'istanza di
HomeConfigutilizzando il contesto della coroutineDispatchers.IOe l'istanza del registro.val homeConfig = HomeConfig( coroutineContext = Dispatchers.IO, factoryRegistry = registry)Infine, crea l'istanza singleton di
Home, che è il punto di accesso alle API, utilizzando il contesto eHomeConfig.val homeManager: HomeClient = Home.getClient(context, homeConfig)
Per evitare errori con sessioni non valide, è importante che venga creata una sola 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 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 in vari servizi Google, ad esempio Google Home, Drive, Maps e così via.
Con l'accesso con Google avviato dall'app, puoi ottenere un'istanza HomeClient
collegata esplicitamente a un determinato utente, bypassando così il selettore dell'Account Google
e la schermata del consenso quando l'account è già autorizzato.
Inoltre, questo approccio impedisce agli utenti di visualizzare due diverse schermate di selezione dell'account: una dall'accesso all'app e una da Google Home.
Per farlo, devi fare riferimento alla sezione Autenticare gli utenti con Accedi con Google e completare i seguenti passaggi:
Creare un ID client web per 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 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. "My App Web Backend").
- Fai clic su Crea.
- Nella pagina Credenziali, fai clic su
- Recupera l'ID client
- Una volta creato, la console mostrerà il nuovo ID client. Questo è il valore che utilizzerai nella tua applicazione Android (ad es. "{project number}-.....apps.googleusercontent.com")
- Ti consigliamo di archiviare l'ID cliente esternamente
(ad es.in
build.gradle) anziché codificarlo direttamente.
Crea un'istanza di una richiesta di accesso a Google
Utilizza l'ID app web per creare una richiesta di accesso 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()
Creare il flusso Accedi 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
la sua email dal token ID Google risultante per creare un
android.accounts.Account. Questo account viene quindi utilizzato per inizializzare un'istanza di HomeClient specificamente associata 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 Home, ma invece di chiamare
Home.getClient(context, homeConfig) nel passaggio 4, chiama
Home.getClient(context, userAccount,
homeConfig),
dove il secondo parametro è un Lazy<UserAccount>. Restituisce un'istanza di
HomeClientWithProvidedAccount,
una sottoclasse di HomeClient, esplicitamente collegata 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 l'autorizzazione chiamando i seguenti metodi sull'istanza HomeClientWithProvidedAccount:
registerActivityResultCallerForPermissions()con un riferimento all'ActivityResultCaller che vuoi utilizzare.requestPermissions(). Viene visualizzata la schermata di consenso di Google Health Connect, 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 del 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 la API Permissions.
Aggiorna l'intera attività con il nuovo HomeClient
Una volta creata una nuova istanza di HomeClient, devi aggiornare l'intera attività per eseguire nuovamente la sottoscrizione e recuperare le strutture, i dispositivi e altri dati pertinenti
associati a questo account utente.
Registrazione di tratti e tipi di dispositivi
La classe FactoryRegistry aiuta gli sviluppatori a ottimizzare le dimensioni del binario dell'app
consentendo loro di indicare esplicitamente quali caratteristiche e tipi di dispositivi vengono utilizzati dalla loro
app.
Tieni presente che le autorizzazioni e il registro di fabbrica sono disaccoppiati. Pertanto,
i tipi e le caratteristiche non registrati disponibili per la tua app tramite le autorizzazioni,
ma non inclusi nel registro di fabbrica, non sono accessibili tramite l'API Automation e non vengono restituiti nelle chiamate ai metodi bulk
traits() o types().