Android で家を初期化する

Android 用 Home API を使用する前に、アプリでホームを初期化する必要があります。このステップでは、ローカル コンテキストの Homeシングルトン インスタンスを作成します。

一度にアクティブにできる Home のインスタンスは 1 つのみです。

これは Home API のエントリ ポイントであり、Device & Structure API と Automation API で使用するトレイトとデバイスタイプを宣言することも含まれます。Google Home エコシステムを使い始めたばかりで、登録する特性やデバイスタイプがわからない場合は、このガイドで一般的な特性やデバイスタイプを紹介しています。

Home インスタンスを作成する

まず、次のパッケージをアプリにインポートします。

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

Home API を初期化するには:

  1. Application コンテキストへの参照を取得します。このコンテキストはアクティビティのライフサイクルに依存せず、アプリが存続する限り存続します。Activity または Service 内で getApplicationContext() を呼び出すことで取得できます。

    val context = getApplicationContext()
    
  2. アプリで使用する予定のすべてのトレイトとデバイスタイプを含む FactoryRegistry インスタンスを作成します。

    このガイドでは、必要なものがわからない場合に備えて、一般的なもの(照明、電源、センサー、スイッチ、サーモスタットのデバイスタイプ、自動化のプレゼンスとアシスタントのトレイト)をいくつか提案しています。詳しくは、トレイトとデバイスタイプの登録をご覧ください。

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

    ここに登録されている個々のトレイトとデバイスタイプごとに、インポート文が必要です(Android Studio で追加するよう求められます)。

  3. Dispatchers.IO コルーチン コンテキストとレジストリ インスタンスを使用して HomeConfig をインスタンス化します。

    val homeConfig = HomeConfig(
            coroutineContext = Dispatchers.IO,
            factoryRegistry = registry)
    
  4. 最後に、コンテキストと HomeConfig を使用して、API のエントリ ポイントである Homeシングルトン インスタンスを作成します。

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

無効なセッションによるエラーを回避するには、オブジェクト宣言でラップして、Home のシングルトン インスタンスのみを作成することが重要です。

たとえば、サンプルアプリでは次のようにします。

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

アプリを起点とする Google ログイン

アプリ内でユーザーの Google 認証を管理したい場合があります。そうすることで、Google Home、ドライブ、マップなどのさまざまな Google サービスで同じユーザー アカウントを使用できます。

アプリから開始される Google ログインを使用すると、特定のユーザーに明示的に関連付けられた HomeClient インスタンスを取得できます。これにより、アカウントがすでに承認されている場合は、Google アカウント選択ツールと同意画面がバイパスされます。

また、このアプローチでは、アプリのログイン画面と Google Home の画面という 2 つのアカウント選択画面がユーザーに表示されるのを防ぐことができます。

これを行うには、Home インスタンスを作成するで説明されている手順と同じ手順を行いますが、ステップ 4 で Home.getClient(context, homeConfig) を呼び出す代わりに、Home.getClient(context, userAccount, homeConfig) を呼び出します。ここで、2 番目のパラメータは Lazy<UserAccount> です。これにより、指定された Google アカウントに明示的に関連付けられた HomeClient のサブクラスである HomeClientWithProvidedAccount のインスタンスが返されます。

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

指定されたユーザーが承認されていない場合は、HomeClientWithProvidedAccount インスタンスで次のメソッドを呼び出して、ユーザーに権限を求めるメッセージを表示します。

  1. 使用する ActivityResultCaller への参照を含む registerActivityResultCallerForPermissions()
  2. requestPermissions()。GHP の同意画面が表示され、ユーザーが権限を付与できます。

UserAccount を使用して HomeClient を作成し、forceLaunch==true を使用して requestPermissions() を呼び出して同意画面を再度起動し、ユーザーが権限付与を更新できるようにします。

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

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

Home API の権限の管理について詳しくは、Permissions API をご覧ください。

トレイトとデバイスタイプの登録

FactoryRegistry クラスを使用すると、アプリで使用される特性とデバイスタイプを明示的に指定できるため、アプリのバイナリサイズを最適化できます。

権限とファクトリー レジストリは分離されています。そのため、権限を使用してアプリで利用できるものの、ファクトリー レジストリに含まれていない未登録のトレイトと型は、Automation API を使用してアクセスすることはできません。また、一括 traits() メソッド呼び出しや types() メソッド呼び出しで返されることもありません。