Zanim zaczniesz korzystać z interfejsów Home API na Androida, musisz zainicjować dom w aplikacji. W tym kroku utworzysz pojedynczą instancję Home dla kontekstu lokalnego.
W danym momencie aktywna powinna być tylko 1 instancja Home.
Jest to punkt wejścia do interfejsów Home API. Wymaga też zadeklarowania, których cech i typów urządzeń zamierzasz używać w interfejsach Device & Structure API i Automation API. Jeśli dopiero zaczynasz korzystać z ekosystemu Google Home i nie wiesz, jakie cechy lub typy urządzeń zarejestrować, w tym przewodniku znajdziesz kilka najpopularniejszych propozycji.
Tworzenie instancji Home
Aby zacząć, zaimportuj do aplikacji te pakiety:
import android.content.Context
import com.google.home.FactoryRegistry
import com.google.home.HomeConfig
import com.google.home.Home
Aby zainicjować interfejsy Home API:
Uzyskaj odniesienie do
Applicationkontekstu. Ten kontekst nie zależy od cyklu życia żadnej aktywności i będzie istniał tak długo, jak długo będzie działać Twoja aplikacja. Możesz go uzyskać, dzwoniąc pod numergetApplicationContext()wActivitylubService:val context = getApplicationContext()Utwórz instancję
FactoryRegistryz wszystkimi cechami i typami urządzeń, których zamierzasz używać w aplikacji.W tym przewodniku proponujemy kilka typowych (typy urządzeń: światło, gniazdko, czujnik, przełącznik i termostat, cechy obecności i Asystenta w przypadku automatyzacji), jeśli nie masz pewności, czego potrzebujesz. Więcej informacji znajdziesz w artykule Rejestracja cech i typów urządzeń.
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))Wymagane są instrukcje importu dla każdego zarejestrowanego tutaj pojedynczego atrybutu i typu urządzenia (Android Studio powinien wyświetlić prośbę o ich dodanie).
Utwórz instancję
HomeConfigza pomocą kontekstu korutynyDispatchers.IOi instancji rejestru.val homeConfig = HomeConfig( coroutineContext = Dispatchers.IO, factoryRegistry = registry)Na koniec utwórz instancję singletonu
Home, która jest punktem wejścia do interfejsów API, używając kontekstu iHomeConfig.val homeManager: HomeClient = Home.getClient(context, homeConfig)
Aby uniknąć błędów związanych z nieprawidłowymi sesjami, ważne jest, aby utworzyć tylko pojedynczą instancję Home, umieszczając ją w deklaracji obiektu.
Na przykład aplikacja przykładowa robi to w ten sposób:
internal object HomeClientModule {
@Provides
@Singleton
fun provideHomeClient(@ApplicationContext context: Context): HomeClient {
return Home.getClient(
context,
HomeConfig(
coroutineContext = IODispatcherModule.provideIoDispatcher(),
factoryRegistry = registry,
),
)
}
}
Logowanie przez Google inicjowane przez aplikację
Możesz zarządzać uwierzytelnianiem użytkowników w Google w ramach swojej aplikacji. Dzięki temu użytkownicy mogą korzystać z tego samego konta w różnych usługach Google, takich jak Google Home, Dysk, Mapy itp.
Dzięki logowaniu przez Google inicjowanemu przez aplikację możesz uzyskać instancję HomeClient wyraźnie powiązaną z określonym użytkownikiem, co pozwala pominąć selektor kont Google i ekran zgody, gdy konto jest już autoryzowane.
Dodatkowo to podejście zapobiega wyświetlaniu użytkownikom dwóch różnych ekranów wyboru konta – jednego z logowania w aplikacji i jednego z Google Home.
Aby to zrobić, zapoznaj się z artykułem Uwierzytelnianie użytkowników za pomocą logowania przez Google i wykonaj te czynności:
Tworzenie identyfikatora klienta aplikacji internetowej OAuth
- Otwórz konsolę Google Cloud.
- Otwórz stronę Dane logowania w konsoli Google Cloud.
- Wybierz istniejący projekt lub utwórz nowy.
- Skonfiguruj ekran zgody OAuth (jeśli jeszcze tego nie zrobiono).
- Zanim utworzysz dane logowania, upewnij się, że ekran akceptacji OAuth jest skonfigurowany z danymi aplikacji, w tym adresami URL polityki prywatności i warunków korzystania z usługi.
- Utwórz identyfikator klienta OAuth (aplikacja internetowa)
- Na stronie Dane logowania kliknij
+ CREATE CREDENTIALSi z menu wybierz Identyfikator klienta OAuth. - Jako Typ aplikacji wybierz Aplikacja internetowa.
- Wpisz nazwę klienta internetowego (np. „My App Web Backend”).
- Kliknij Utwórz.
- Na stronie Dane logowania kliknij
- Pobieranie identyfikatora klienta
- Po utworzeniu konsola wyświetli nowy identyfikator klienta. Jest to wartość, której będziesz używać w aplikacji na Androida (np. „{project number}-.....apps.googleusercontent.com”).
- Zalecamy przechowywanie identyfikatora klienta na zewnątrz (np.w
build.gradle) zamiast umieszczania go bezpośrednio w kodzie.
Utwórz instancję żądania logowania się przez Google
Użyj identyfikatora aplikacji internetowej, aby utworzyć żądanie logowania przez 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()
Tworzenie procedury logowania się przez Google
Aby wdrożyć proces logowania, użyj CredentialManager do wykonania żądania Sign in with Google. Gdy użytkownik wybierze konto, wyodrębnij jego adres e-mail z otrzymanego tokena identyfikatora Google, aby utworzyć android.accounts.Account. To konto jest następnie używane do inicjowania instancji HomeClient powiązanej z tym zalogowanym użytkownikiem.
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)
}
Uzyskiwanie nowej instancji HomeClient
Wykonaj te same czynności, które opisano w sekcji Tworzenie instancji Home, ale zamiast wywoływać Home.getClient(context, homeConfig) w kroku 4, wywołaj Home.getClient(context, userAccount,
homeConfig), gdzie drugi parametr to Lazy<UserAccount>. Zwraca to instancję klasy HomeClientWithProvidedAccount, podklasy klasy HomeClient, która jest wyraźnie powiązana z określonym kontem 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()
)
Jeśli określony użytkownik nie jest autoryzowany, poproś go o zezwolenie, wywołując te metody na instancji HomeClientWithProvidedAccount:
registerActivityResultCallerForPermissions()z odwołaniem do interfejsu ActivityResultCaller, którego chcesz użyć.requestPermissions()Wyświetli się ekran zgody platformy GHP, na którym użytkownik może przyznać uprawnienia.
Możesz utworzyć HomeClient z UserAccount, a następnie wywołać requestPermissions() z forceLaunch==true, aby ponownie wyświetlić ekran zgody i umożliwić użytkownikowi zaktualizowanie przyznanych uprawnień:
val client =
Home.getClient(
context = context.applicationContext,
account =
lazy {
UserAccount.GoogleAccount(androidAccount)
},
homeConfig = HomeConfig()
)
client.registerActivityResultCallerForPermissions(this)
client.requestPermissions(forceLaunch= true)
Więcej informacji o zarządzaniu uprawnieniami interfejsów API Home znajdziesz w artykule Interfejs API uprawnień.
Odśwież całą aktywność za pomocą nowego HomeClient
Gdy uzyskasz nową instancję HomeClient, musisz odświeżyć całą aktywność, aby ponownie zasubskrybować i pobrać pełne struktury, urządzenia i inne istotne dane powiązane z tym kontem użytkownika.
Rejestracja cech i typów urządzeń
Klasa FactoryRegistry pomaga deweloperom optymalizować rozmiar pliku binarnego aplikacji, ponieważ umożliwia im wyraźne wskazanie, które cechy i typy urządzeń są używane przez aplikację.
Uprawnienia i rejestr fabryczny są od siebie niezależne. Dlatego niezarejestrowane cechy i typy, które są dostępne dla aplikacji za pomocą uprawnień, ale nie są uwzględnione w rejestrze fabrycznym, są niedostępne za pomocą interfejsu Automation API ani nie są zwracane w wywołaniach metod zbiorczych traits() ani types().