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`](https://developers.home.google.com/apis/android/initialize#create_a_home_instance) 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:

```kotlin
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`](https://developer.android.com/reference/android/app/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`:

   ```kotlin
   val context = getApplicationContext()
   ```
2. Create a [`FactoryRegistry`](https://developers.home.google.com/reference/kotlin/com/google/home/FactoryRegistry.md.txt)
   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](https://developers.home.google.com/apis/android/initialize.md.txt#register).

   ```kotlin
   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`](https://developers.home.google.com/reference/kotlin/com/google/home/HomeConfig.md.txt)
   using the
   [`Dispatchers.IO`](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/#-978510185%2FProperties%2F-1316292404)
   coroutine context and your registry instance.

   ```kotlin
   val homeConfig = HomeConfig(
           coroutineContext = Dispatchers.IO,
           factoryRegistry = registry)
   ```
4. Finally, create the **singleton** instance of
   [`Home`](https://developers.home.google.com/reference/kotlin/com/google/home/Home.md.txt), which is the entry point to
   the APIs, using the context and the `HomeConfig`.

   ```kotlin
   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](https://kotlinlang.org/docs/object-declarations.html).

For an example, the [Sample App](https://developers.home.google.com/apis/sample-app/build) does it this way:

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

If you want Google-hosted UI flows, such as the Permissions consent screen, to
render in a specific language, call `setLocale()` on your `HomeClient` instance
before requesting permissions. For details, see
[Configure the app locale](https://developers.home.google.com/apis/android/initialize.md.txt#configure-locale).

### 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, you must refer to [Authenticate users with Sign in with Google](https://developer.android.com/identity/sign-in/credential-manager-siwg) and complete the following steps:

#### Create an OAuth web application client ID

1. Open the Google Cloud Console
   - Navigate to the Google Cloud Console Credentials page.
   - Select an existing project or create a new one.
2. Configure the OAuth Consent Screen (if you haven't)
   - Before creating credentials, ensure the OAuth consent screen is configured with your app's details, including privacy policy and terms of service URLs.
3. Create an OAuth Client ID (Web Application type)
   - On the Credentials page, click `+ CREATE CREDENTIALS` and select **OAuth client ID** from the drop-down menu.
   - For the **Application type** , select **Web application**.
   - Enter a name for your web client (e.g., "My App Web Backend").
   - Click Create.
4. Retrieve the Client ID
   - After creation, the console will display your new Client ID. This is the value you will use in your Android application (e.g. "*{project number}-.....apps.googleusercontent.com*")
   - It is recommended that you store the Client ID externally (e.g., in `build.gradle`) rather than hardcoding it directly

#### Instantiate a Google Sign-In request

Use the web app ID to create a Google sign-in request:

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

#### Create the Sign in with Google flow

To implement the sign-in flow, use `CredentialManager` to execute a
`Sign in with Google` request. Once the user selects an account, extract
their email from the resulting Google ID Token to create an
`android.accounts.Account`. This account is then used to initialize a
`HomeClient` instance specifically tied to that signed-in user.

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

#### Get a new HomeClient instance

Follow the same steps outlined in
[Create a Home instance](https://developers.home.google.com/apis/android/initialize.md.txt#create_a_home_instance), but instead of calling
`Home.getClient(context, homeConfig)` in Step 4, call
[`Home.getClient(context, userAccount,
homeConfig)`](https://developers.home.google.com/reference/kotlin/com/google/home/Home#getClient(android.content.Context,kotlin.Lazy,com.google.home.HomeConfig)),
where the second parameter is a `Lazy<UserAccount>`. This returns an instance of
[`HomeClientWithProvidedAccount`](https://developers.home.google.com/reference/kotlin/com/google/home/HomeClientWithProvidedAccount.md.txt),
a subclass of `HomeClient`, that's explicitly tied to the specified Google
Account:

```kotlin
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`](https://developers.home.google.com/reference/kotlin/com/google/home/HomeClientWithProvidedAccount.md.txt)
instance:

1. [`registerActivityResultCallerForPermissions()`](https://developers.home.google.com/reference/kotlin/com/google/home/Home.md.txt#registerActivityResultCallerForPermissions(androidx.activity.result.ActivityResultCaller)) with a reference to the [ActivityResultCaller](https://developer.android.com/reference/androidx/activity/result/ActivityResultCaller.html) you want to use.
2. [`requestPermissions()`](https://developers.home.google.com/reference/kotlin/com/google/home/Home.md.txt#requestPermissions(kotlin.Boolean)). This brings up the GHP Consent screen, where the user can grant their permission.

You can create a `HomeClient` with a
[`UserAccount`](https://developers.home.google.com/reference/kotlin/com/google/home/UserAccount.md.txt) and then call
`requestPermissions()` with `forcePermissionFlow` set to
`ForcePermissionFlow.FORCE_LAUNCH` to launch the consent screen again to allow
the user to update their permissions grant:

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

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

To display the consent screen in a specific language, call `client.setLocale()`
before calling `requestPermissions()`. See
[Configure the app locale](https://developers.home.google.com/apis/android/initialize.md.txt#configure-locale) for details, and see
[Permissions API](https://developers.home.google.com/apis/permissions) for more information on managing Home APIs
permissions.

#### Refresh the whole activity with the new HomeClient

Once you have a new `HomeClient` instance, you must refresh the entire activity to resubscribe and fetch the complete structures, devices, and other pertinent data
associated with this user account.

### 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](https://developers.home.google.com/apis/android/automation.md.txt) nor are they returned in the bulk
`traits()` or `types()` method calls.
Device groups are represented by the [`DeviceGroup`](https://developers.home.google.com/reference/kotlin/com/google/home/DeviceGroup.md.txt) entity, which is distinct from [`HomeDevice`](https://developers.home.google.com/reference/kotlin/com/google/home/HomeDevice.md.txt). To query and interact with device groups, include `DeviceGroup` in the `entityTypes` list when initializing your [`FactoryRegistry`](https://developers.home.google.com/reference/kotlin/com/google/home/FactoryRegistry.md.txt), along with the [`Group`](https://developers.home.google.com/reference/kotlin/com/google/home/google/Group.md.txt), [`GroupManagement`](https://developers.home.google.com/reference/kotlin/com/google/home/google/GroupManagement.md.txt), and [`GroupMembership`](https://developers.home.google.com/reference/kotlin/com/google/home/google/GroupMembership.md.txt) traits.

For more information, see
[Device groups](https://developers.home.google.com/apis/android/structure.md.txt#device-groups).

## Configure the app locale

Use `setLocale()` and `getLocale()` on your
[`HomeClient`](https://developers.home.google.com/reference/kotlin/com/google/home/HomeClient) instance to
configure and retrieve the language preference for your app. The locale must be
a valid BCP-47 language tag, such as `"en-US"`, `"en-GB"`, or `"ja"`.

When you set a locale on `HomeClient`, the Home APIs use that language for
Google-hosted UI flows, including the Permissions UI,
Matter commissioning, and device removal flows. If you
don't set a locale, these flows default to the app or device locale.

- Calling `setLocale()` before the user signs in and grants permissions stores the locale in memory and applies it to the initial Permissions UI flow. Once the user signs in and a structure is available, the SDK syncs the locale with the cloud. If the user already has a saved locale in the cloud for your app, the cloud setting takes precedence on initial sync.
- Calling `setLocale()` while signed in updates the locale in memory and persists it to the cloud for that user and app.

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

### Sync with Android per-app language preferences

If your app supports Android per-app language preferences using
[`LocaleManager`](https://developer.android.com/guide/topics/resources/app-languages),
call `homeManager.setLocale()` before updating
`LocaleManager.applicationLocales`. Updating `applicationLocales` recreates the
active `Activity`, which can cancel an in-flight coroutine if you call
`setLocale()` afterward.

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