Android'de evi başlatma

Android için Home API'lerini kullanmadan önce uygulamanızda evi başlatmanız gerekir. Bu adımda, yerel bağlam için singleton örneği Home oluşturacaksınız.

Aynı anda yalnızca bir Home örneği etkin olmalıdır.

Bu, Home API'lerin giriş noktasıdır ve Device & Structure ve Automation API'leriyle kullanmak istediğiniz özellikleri ve cihaz türlerini beyan etmeyi de içerir. Google Home ekosistemini kullanmaya yeni başladıysanız ve hangi özellikleri veya cihaz türlerini kaydetmeniz gerektiğinden emin değilseniz bu kılavuzda en yaygın olanlardan bazılarını önerdik.

Home örneği oluşturma

Başlamak için bu paketleri uygulamanıza aktarın:

import android.content.Context
import com.google.home.FactoryRegistry
import com.google.home.HomeConfig
import com.google.home.Home

Ana Sayfa API'lerini ilk kullanıma hazırlamak için:

  1. Application bağlamına referans alın. Bu bağlam, herhangi bir etkinlik yaşam döngüsüne bağlı değildir ve uygulamanız etkin olduğu sürece etkin kalır. getApplicationContext() yöntemini bir Activity veya Service içinde çağırarak elde edebilirsiniz:

    val context = getApplicationContext()
    
  2. Uygulamanızda kullanmak istediğiniz tüm özelliklere ve cihaz türlerine sahip bir FactoryRegistry örneği oluşturun.

    Bu kılavuzda, neye ihtiyacınız olduğundan emin değilseniz diye bazı yaygın türleri (Işık, Priz, Sensör, Anahtar ve Termostat cihaz türleri, otomasyonlar için varlık ve Asistan özellikleri) önerdik. Daha fazla bilgi edinmek için Özelliklerin ve cihaz türlerinin kaydı başlıklı makaleyi inceleyin.

    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))
    

    Burada kayıtlı her bir özellik ve cihaz türü için içe aktarma ifadeleri gereklidir (Android Studio bunları eklemenizi ister).

  3. Dispatchers.IO eş yordam bağlamını ve kayıt örneğinizi kullanarak bir HomeConfig örneklendirin.

    val homeConfig = HomeConfig(
            coroutineContext = Dispatchers.IO,
            factoryRegistry = registry)
    
  4. Son olarak, bağlamı ve HomeConfig kullanarak API'lerin giriş noktası olan Home'nin singleton örneğini oluşturun.

    val homeManager: HomeClient = Home.getClient(context, homeConfig)
    

Geçersiz oturumlarla ilgili hataları önlemek için Home'ün yalnızca bir singleton örneğinin oluşturulması ve bunun bir nesne bildirimine sarmalanması önemlidir.

Örneğin, Örnek Uygulama bunu şu şekilde yapar:

internal object HomeClientModule {
  @Provides
  @Singleton
  fun provideHomeClient(@ApplicationContext context: Context): HomeClient {
    return Home.getClient(
      context,
      HomeConfig(
        coroutineContext = IODispatcherModule.provideIoDispatcher(),
        factoryRegistry = registry,
      ),
    )
  }
}

İzin kullanıcı rızası ekranı gibi Google tarafından barındırılan kullanıcı arayüzü akışlarının belirli bir dilde oluşturulmasını istiyorsanız izin istemeden önce HomeClient örneğinizde setLocale() yöntemini çağırın. Ayrıntılar için Uygulama yerel ayarını yapılandırma başlıklı makaleyi inceleyin.

Uygulama tarafından başlatılan Google ile oturum açma

Kullanıcınızın Google kimlik doğrulamalarını uygulamanızda yönetmek isteyebilirsiniz. Böylece Google Home, Drive, Haritalar gibi çeşitli Google hizmetlerinde aynı kullanıcı hesabını kullanabilirsiniz.

Uygulama tarafından başlatılan Google ile oturum açma özelliği sayesinde, belirli bir kullanıcıya açıkça bağlı bir HomeClient örneği elde edebilirsiniz. Böylece, hesap zaten yetkilendirilmişse Google Hesabı seçiciyi ve kullanıcı rızası ekranını atlayabilirsiniz.

Ayrıca bu yaklaşım, kullanıcıların iki farklı hesap seçim ekranı (biri uygulamanın oturum açma ekranından, diğeri Google Home'dan) görmesini engeller.

Bunun için Google ile oturum açma özelliğini kullanarak kullanıcıların kimliğini doğrulama başlıklı makaleyi incelemeniz ve aşağıdaki adımları uygulamanız gerekir:

OAuth web uygulaması istemci kimliği oluşturma

  1. Google Cloud Console'u açın.
    • Google Cloud Console Kimlik Bilgileri sayfasına gidin.
    • Mevcut bir projeyi seçin veya yeni bir proje oluşturun.
  2. OAuth kullanıcı rızası ekranını yapılandırın (henüz yapmadıysanız).
    • Kimlik bilgilerini oluşturmadan önce OAuth kullanıcı rızası ekranının, gizlilik politikası ve hizmet şartları URL'leri de dahil olmak üzere uygulamanızın ayrıntılarıyla yapılandırıldığından emin olun.
  3. OAuth istemci kimliği (web uygulaması türü) oluşturun.
    • Kimlik Bilgileri sayfasında + CREATE CREDENTIALS simgesini tıklayın ve açılır menüden OAuth istemci kimliği'ni seçin.
    • Application type (Uygulama türü) için Web application'ı (Web uygulaması) seçin.
    • Web istemciniz için bir ad girin (ör. "Uygulamamın Web Arka Ucu").
    • Oluştur'u tıklayın.
  4. İstemci kimliğini alma
    • Oluşturulduktan sonra konsolda yeni istemci kimliğiniz gösterilir. Bu, Android uygulamanızda kullanacağınız değerdir (ör. "{project number}-.....apps.googleusercontent.com").
    • İstemci kimliğini doğrudan sabit kodlamak yerine harici olarak (ör.build.gradle içinde) depolamanız önerilir.

Google ile Oturum Açma isteği oluşturma

Google ile oturum açma isteği oluşturmak için web uygulaması kimliğini kullanın:

// 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()

Google ile oturum açma akışını oluşturma

Oturum açma akışını uygulamak için CredentialManager kullanarak bir Sign in with Google isteği yürütün. Kullanıcı bir hesap seçtikten sonra, android.accounts.Account oluşturmak için kullanıcının e-posta adresini Google kimlik jetonundan çıkarın. Bu hesap daha sonra, oturum açmış olan kullanıcıya özel olarak bağlı bir HomeClient örneğini başlatmak için kullanılır.

  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)
  }

Yeni bir HomeClient örneği alma

Ana örnek oluşturma bölümünde açıklanan adımları uygulayın ancak 4. adımda Home.getClient(context, homeConfig) yerine Home.getClient(context, userAccount, homeConfig) yöntemini çağırın. İkinci parametre Lazy<UserAccount> olmalıdır. Bu işlem, belirtilen Google Hesabı'na açıkça bağlı olan HomeClient alt sınıfı HomeClientWithProvidedAccount'in bir örneğini döndürür:

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()
     )

Belirtilen kullanıcı yetkili değilse HomeClientWithProvidedAccount örneğinde aşağıdaki yöntemleri çağırarak kullanıcıdan izin isteyin:

  1. Kullanmak istediğiniz ActivityResultCaller'a referans veren registerActivityResultCallerForPermissions().
  2. requestPermissions(). Bu işlem, kullanıcının izin verebileceği GHP kullanıcı rızası ekranını açar.

UserAccount ile bir HomeClient oluşturabilir ve ardından ForcePermissionFlow.FORCE_LAUNCH olarak ayarlanmış forcePermissionFlow ile requestPermissions() yöntemini çağırarak kullanıcı rızası ekranını tekrar başlatıp kullanıcının izinlerini güncellemesine olanak tanıyabilirsiniz:

val client =
     Home.getClient(
       context = context.applicationContext,
       account =
         lazy {
              UserAccount.GoogleAccount(androidAccount)
         },
       homeConfig = HomeConfig()
     )

client.registerActivityResultCallerForPermissions(this)
client.requestPermissions(forcePermissionFlow = ForcePermissionFlow.FORCE_LAUNCH)

Kullanıcı rızası ekranını belirli bir dilde görüntülemek için requestPermissions() yöntemini çağırmadan önce client.setLocale() yöntemini çağırın. Ayrıntılar için Uygulama yerel ayarını yapılandırma bölümüne, Home API'leri izinlerini yönetme hakkında daha fazla bilgi için Permissions API bölümüne bakın.

Yeni HomeClient ile tüm etkinliği yenileme

Yeni bir HomeClient örneğiniz olduğunda, yeniden abone olmak ve bu kullanıcı hesabıyla ilişkili tüm yapıları, cihazları ve diğer ilgili verileri almak için etkinliğin tamamını yenilemeniz gerekir.

Özelliklerin ve cihaz türlerinin kaydı

FactoryRegistry sınıfı, geliştiricilerin uygulamaları tarafından kullanılan özellikleri ve cihaz türlerini açıkça belirtmelerine olanak tanıyarak uygulama ikili program boyutunu optimize etmelerine yardımcı olur.

İzinlerin ve fabrika kayıt defterinin birbirinden ayrı olduğunu unutmayın. Bu nedenle, uygulamanızın izinleri kullanarak erişebildiği ancak fabrika kayıt defterine dahil edilmeyen kayıtlı olmayan özelliklere ve türlere Automation API kullanılarak erişilemez ve bunlar toplu traits() veya types() yöntem çağrılarında döndürülmez.

Cihaz grupları, HomeDevice öğesinden farklı olan DeviceGroup varlığıyla temsil edilir. Cihaz gruplarını sorgulamak ve onlarla etkileşimde bulunmak için FactoryRegistry öğenizi başlatırken entityTypes listesine DeviceGroup özelliğini, Group, GroupManagement ve GroupMembership özellikleriyle birlikte ekleyin.

Daha fazla bilgi için Cihaz grupları başlıklı makaleyi inceleyin.

Uygulama yerel ayarını yapılandırma

Uygulamanızın dil tercihini yapılandırmak ve almak için HomeClient örneğinizde setLocale() ve getLocale() kullanın. Yerel ayar, geçerli bir BCP-47 dil etiketi (ör. "en-US", "en-GB" veya "ja") olmalıdır.

HomeClient üzerinde bir yerel ayar belirlediğinizde Home API'leri, Google tarafından barındırılan kullanıcı arayüzü akışları için bu dili kullanır. Bu akışlara izinler kullanıcı arayüzü, Matter yetkilendirme ve cihaz kaldırma akışları dahildir. Yerel ayar belirlemezseniz bu akışlar varsayılan olarak uygulama veya cihaz yerel ayarını kullanır.

  • Kullanıcı oturum açıp izinleri vermeden önce setLocale() çağrıldığında yerel ayar belleğe kaydedilir ve ilk izin kullanıcı arayüzü akışına uygulanır. Kullanıcı oturum açtıktan ve bir yapı kullanılabilir olduktan sonra SDK, yerel ayarı bulutla senkronize eder. Kullanıcının uygulamanız için bulutta kayıtlı bir yerel ayarı varsa ilk senkronizasyonda bulut ayarı öncelikli olur.
  • Oturum açılmışken setLocale() çağrıldığında bellekteki yerel ayar güncellenir ve söz konusu kullanıcı ile uygulama için buluta kaydedilir.
// Set the locale using a BCP-47 language tag
coroutineScope.launch {
  homeManager.setLocale("ja")
}

// Retrieve the configured locale, or null if not set
val currentLocale: String? = homeManager.getLocale()

Android'in uygulamaya özgü dil tercihleriyle senkronize etme

Uygulamanız LocaleManager kullanarak Android'de uygulamaya özgü dil tercihlerini destekliyorsa LocaleManager.applicationLocales güncellemeden önce homeManager.setLocale() çağrısı yapın. applicationLocales güncellendiğinde etkin Activity yeniden oluşturulur. Bu durumda, daha sonra setLocale() çağrılırsa devam eden bir eş yordam iptal edilebilir.

coroutineScope.launch {
  val languageTag = "fr-CA"

  // 1. Persist the locale to HomeClient first
  homeManager.setLocale(languageTag)

  // 2. Update Android's per-app locale (recreates the Activity)
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    context.getSystemService(LocaleManager::class.java).applicationLocales =
      LocaleList.forLanguageTags(languageTag)
  }
}