Melakukan inisialisasi rumah di Android

Sebelum menggunakan salah satu Home API untuk Android, Anda harus melakukan inisialisasi rumah di aplikasi Anda. Pada langkah ini, Anda akan membuat instance singleton dari Home untuk konteks lokal.

Hanya satu instance Home yang boleh aktif dalam satu waktu.

Ini adalah titik entri ke Home API dan juga melibatkan deklarasi sifat dan jenis perangkat yang ingin Anda gunakan dengan Device & Structure API dan Automation API. Jika Anda baru mulai menggunakan ekosistem Google Home dan tidak yakin jenis perangkat atau karakteristik apa yang harus didaftarkan, kami telah menyarankan beberapa jenis perangkat yang paling umum di sini dalam panduan ini.

Membuat instance Rumah

Untuk memulai, impor paket ini ke aplikasi Anda:

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

Untuk menginisialisasi Home API:

  1. Dapatkan referensi ke konteks Application. Konteks ini tidak bergantung pada siklus proses aktivitas apa pun, dan akan tetap ada selama aplikasi Anda aktif. Anda dapat memperolehnya dengan memanggil getApplicationContext() dalam Activity atau Service:

    val context = getApplicationContext()
    
  2. Buat instance FactoryRegistry dengan semua karakteristik dan jenis perangkat yang ingin Anda gunakan di aplikasi.

    Untuk panduan ini, kami telah menyarankan beberapa jenis perangkat umum (Light, Plug, Sensor, Switch, dan Thermostat, serta kehadiran dan sifat Asisten untuk otomatisasi), jika Anda tidak yakin dengan apa yang Anda butuhkan. Untuk mempelajari lebih lanjut, lihat Pendaftaran karakteristik dan jenis perangkat.

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

    Pernyataan impor untuk setiap jenis perangkat dan karakteristik individual yang terdaftar di sini diperlukan (Android Studio akan meminta Anda untuk menambahkannya).

  3. Buat instance HomeConfig menggunakan konteks coroutine Dispatchers.IO dan instance registry Anda.

    val homeConfig = HomeConfig(
            coroutineContext = Dispatchers.IO,
            factoryRegistry = registry)
    
  4. Terakhir, buat instance singleton dari Home, yang merupakan titik entri ke API, menggunakan konteks dan HomeConfig.

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

Untuk menghindari error pada sesi yang tidak valid, hanya satu instance singleton dari Home yang dibuat, dengan membungkusnya dalam deklarasi objek.

Sebagai contoh, Sample App melakukannya dengan cara ini:

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

Login dengan Google yang dimulai aplikasi

Anda mungkin ingin mengelola autentikasi Google pengguna dalam aplikasi Anda. Dengan melakukannya, Anda dapat menggunakan akun pengguna yang sama di berbagai layanan Google seperti Google Home, Drive, Maps, dan sebagainya.

Dengan login dengan Google yang dimulai aplikasi, Anda dapat memperoleh instance HomeClient yang terikat secara eksplisit ke pengguna tertentu, sehingga melewati pemilih Akun Google dan layar izin saat akun sudah diberi otorisasi.

Selain itu, pendekatan ini mencegah pengguna melihat dua layar pemilihan akun yang berbeda - satu dari login aplikasi dan satu dari Google Home.

Untuk melakukannya, Anda harus membaca Mengautentikasi pengguna dengan Login dengan Google dan menyelesaikan langkah-langkah berikut:

Buat client ID aplikasi web OAuth

  1. Buka Konsol Google Cloud
    • Buka halaman Kredensial Google Cloud Console.
    • Pilih project yang ada atau buat project baru.
  2. Mengonfigurasi Layar Izin OAuth (jika belum)
    • Sebelum membuat kredensial, pastikan layar izin OAuth dikonfigurasi dengan detail aplikasi Anda, termasuk URL kebijakan privasi dan persyaratan layanan.
  3. Buat Client ID OAuth (jenis Aplikasi Web)
    • Di halaman Credentials, klik + CREATE CREDENTIALS dan pilih OAuth client ID dari menu drop-down.
    • Untuk Application type, pilih Web application.
    • Masukkan nama untuk klien web Anda (misalnya, "My App Web Backend").
    • Klik Buat.
  4. Mengambil ID Klien
    • Setelah dibuat, konsol akan menampilkan Client ID baru Anda. Nilai ini akan Anda gunakan di aplikasi Android Anda (misalnya, "{project number}-.....apps.googleusercontent.com")
    • Sebaiknya simpan ID Klien secara eksternal (misalnya, di build.gradle), bukan dengan melakukan hardcoding secara langsung

Membuat instance permintaan Login dengan Google

Gunakan ID aplikasi web untuk membuat permintaan login dengan 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()

Membuat alur Login dengan Google

Untuk menerapkan alur login, gunakan CredentialManager untuk menjalankan permintaan Sign in with Google. Setelah pengguna memilih akun, ekstrak emailnya dari Token ID Google yang dihasilkan untuk membuat android.accounts.Account. Akun ini kemudian digunakan untuk menginisialisasi instance HomeClient yang secara khusus terikat dengan pengguna yang login tersebut.

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

Dapatkan instance HomeClient baru

Ikuti langkah-langkah yang sama yang diuraikan dalam Membuat instance Home, tetapi alih-alih memanggil Home.getClient(context, homeConfig) pada Langkah 4, panggil Home.getClient(context, userAccount, homeConfig), dengan parameter kedua adalah Lazy<UserAccount>. Tindakan ini akan menampilkan instance HomeClientWithProvidedAccount, subclass dari HomeClient, yang secara eksplisit terkait dengan Akun Google yang ditentukan:

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

Jika pengguna yang ditentukan tidak diberi otorisasi, minta izin pengguna dengan memanggil metode berikut pada instance HomeClientWithProvidedAccount:

  1. registerActivityResultCallerForPermissions() dengan referensi ke ActivityResultCaller yang ingin Anda gunakan.
  2. requestPermissions(). Tindakan ini akan menampilkan layar Izin GHP, tempat pengguna dapat memberikan izin mereka.

Anda dapat membuat HomeClient dengan UserAccount, lalu memanggil requestPermissions() dengan forceLaunch==true untuk meluncurkan layar izin lagi agar pengguna dapat memperbarui pemberian izin mereka:

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

client.registerActivityResultCallerForPermissions(this)
client.requestPermissions(forceLaunch= true)

Lihat Permissions API untuk mengetahui informasi selengkapnya tentang cara mengelola izin Home API.

Muat ulang seluruh aktivitas dengan HomeClient baru

Setelah memiliki instance HomeClient baru, Anda harus memuat ulang seluruh aktivitas untuk berlangganan ulang dan mengambil struktur, perangkat, dan data relevan lainnya yang terkait dengan akun pengguna ini.

Pendaftaran fitur dan jenis perangkat

Class FactoryRegistry membantu developer mengoptimalkan ukuran biner aplikasi mereka dengan memungkinkan mereka secara eksplisit menunjukkan sifat dan jenis perangkat yang digunakan oleh aplikasi mereka.

Perhatikan bahwa izin dan registry pabrik tidak terkait. Oleh karena itu, jenis dan karakteristik yang tidak terdaftar yang tersedia untuk aplikasi Anda menggunakan izin, tetapi tidak disertakan dalam pendaftaran pabrik tidak dapat diakses menggunakan Automation API dan tidak ditampilkan dalam panggilan metode traits() atau types() massal.