Zanim zaczniesz używać interfejsów Home API na Androidzie, musisz zainicjować dom w aplikacji. W tym kroku utworzysz instancję singleton klasy Home dla kontekstu lokalnego.
W danym momencie aktywna może być tylko jedna 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 te pakiety do aplikacji:
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 działa aplikacja. Możesz go uzyskać, dzwoniąc pod numergetApplicationContext()wActivitylubService:val context = getApplicationContext()Utwórz instancję
FactoryRegistryze wszystkimi cechami i typami urządzeń, których chcesz 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 jedną 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 (typ aplikacji internetowej).
- 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 identyfikator klienta pojawi się w konsoli. 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 bezpośredniego kodowania go na stałe.
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 w 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 wyrazić zgodę.
Możesz utworzyć HomeClient za pomocą 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, umożliwiając im wyraźne wskazanie, które cechy i typy urządzeń są używane przez aplikację.
Pamiętaj, że 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().