Initialize the home on Android

Before using any of the Home APIs for Android, you must initialize the home in your app. In this step, you'll create a singleton instance of Home for the local context.

Only one instance of Home should be active at a time.

This is the entry point to the Home APIs and also involves declaring which traits and device types you intend to use with the Device & Structure and Automation APIs. If you're just starting out with the Google Home ecosystem and are not sure what traits or device types to register, we've suggested some of the most common here in this guide.

Create a Home instance

To begin, import these packages into your app:

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

To initialize the Home APIs:

  1. Get a reference to the Application context. This context doesn't depend on any activity lifecycle, and will live as long as your app is alive. You can obtain it by calling getApplicationContext() within an Activity or Service:

    val context = getApplicationContext()
    
  2. Create a FactoryRegistry instance with all the traits and device types you intend to use in your app.

    For this guide, we've suggested some common ones (Light, Plug, Sensor, Switch, and Thermostat device types, presence and Assistant traits for automations), in case you're not sure what you need. To learn more, see Registration of traits and device types.

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

    Import statements for each individual trait and device type registered here are required (Android Studio should prompt you to add these).

  3. Instantiate a HomeConfig using the Dispatchers.IO coroutine context and your registry instance.

    val homeConfig = HomeConfig(
            coroutineContext = Dispatchers.IO,
            factoryRegistry = registry)
    
  4. Finally, create the singleton instance of Home, which is the entry point to the APIs, using the context and the HomeConfig.

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

To avoid errors with invalid sessions, it is important that only a singleton instance of Home is created, by wrapping it in an object declaration.

For an example, the Sample App does it this way:

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

App-initiated Google sign-in

You may want to manage your user's Google authentications within your app. Doing so lets you use the same user account across various Google services such as Google Home, Drive, Maps, and so forth.

With app-initiated Google sign-in, you can obtain a HomeClient instance explicitly tied to a particular user, thereby bypassing Google Account picker and consent screen when the account is already authorized.

Additionally, this approach prevents users from seeing two different account selection screens - one from the app's sign-in and one from the Google Home.

To do this, follow the same steps outlined in Create a Home instance, but instead of calling Home.getClient(context, homeConfig) in Step 4, call Home.getClient(context, userAccount, homeConfig), where the second parameter is a Lazy<UserAccount>. This returns an instance of HomeClientWithProvidedAccount, a subclass of HomeClient, that's explicitly tied to the specified Google Account:

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

If the specified user isn't authorized, prompt the user for their permission by calling the following methods on the HomeClientWithProvidedAccount instance:

  1. registerActivityResultCallerForPermissions() with a reference to the ActivityResultCaller you want to use.
  2. requestPermissions(). This brings up the GHP Consent screen, where the user can grant their permission.

You can create a HomeClient with a UserAccount and then call requestPermissions() with forceLaunch==true to launch the consent screen again to allow the user to update their permissions grant:

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

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

See Permissions API for more information on managing Home APIs permissions.

Registration of traits and device types

The FactoryRegistry class helps developers optimize their app binary size by letting them explicitly indicate which traits and device types are used by their app.

Note that permissions and the factory registry are decoupled. Therefore, unregistered traits and types that are available to your app using permissions but not included in the factory registry are inaccessible using the Automation API nor are they returned in the bulk traits() or types() method calls.