重要な Android アプリを作成する

1. ようこそ

IoT 標準の統一を目指して構築された Matter は、Google Home、Zigbee、Bluetooth Mesh、Z-Wave などのさまざまなエコシステムにわたってスマートホーム デバイスを接続します。

モバイル デバイスは、スマートホーム デバイスとの主なインタラクション ポイントです。Matter 対応デバイスをサポートする独自の Android アプリを作成したい場合は、Google が迅速な構築をお手伝いします。

Matter 向けの Google Home サンプルアプリ(Matter 向けの GHSA)は、ユーザーがデバイスのコミッショニングと共有を行える Home Mobile SDK API を紹介するものです。また、サンプルアプリは、Matter の主なコンセプトについての理解を深めるための学習ツールとして、また Matter 対応デバイスの操作のデバッグやトラブルシューティングを行うツールとしても活用できます。

演習内容

この Codelab では、サンプルアプリのソースコードをダウンロードし、Home Mobile SDK を使用してデバイスのコミッショニングと共有を行う方法を学びます。また、Matter リポジトリ(connectedhomeipでコミッショニングとクラスタ ライブラリの使用方法についても説明します。

サンプルアプリをダウンロードすると、Google が Android Studio でソースコードを確認し、次の Home Mobile SDK API を実装します。

また、コミッショニングのコンセプト、Matter ファブリック、Matter デバイスの操作方法についても説明します。

必要なもの

始める前に、必ず次の手順を完了してください。

サンプルアプリでデバイスのコミッショニングと制御に Google Nest Hub(第 2 世代)などのハブは必要ありません。

2. セットアップする

Codelab のスターター アプリは codelab ブランチにあります。Codelab のソースコードの使用を開始するには、ZIP ファイルをダウンロードします。

この codelab ZIP ファイルを使用して、作業用のサンプルを作成します。

Codelab のバージョン

codelab ブランチは、サンプルアプリの 2.0.0 リリースでタグ付けされます。各ステップを進めながら更新を比較するには、このリリースの完全なソースコードをダウンロードします。

GitHub リポジトリのクローンを作成する場合は、サンプルアプリの README の手順に沿って操作してください。

依存関係

ここではデバイスの共有とコミッションに必要なソースコードについて説明しますが、始める前に次の依存関係を認識しておくことをおすすめします。これらの依存関係は libs.versions.toml ファイルで宣言されており、それらの使用方法は build.gradle.kts ファイルで指定されています。

ソースコード

ユーザー インターフェースとほとんどの機能はすでに作成されています。

この Codelab では、次のファイルに Matter 機能を追加します。

  • java/commissioning/AppCommissioningService: デバイスを開発ファブリックにコミッショニングできます。
  • java/screens/home/HomeScreenjava/screens/home/HomeViewModel.kt: Home Mobile SDK のコミッショニング機能を含みます。
  • java/screens/device/DeviceScreenjava/screens/device/DeviceViewModel: Share Device API 呼び出しを含む

各ファイルには、変更するコードブロックを使用してコメント化します。次に例を示します。

// CODELAB: add commissioningFunction()

これにより、Codelab の対応するセクションをすばやく見つけることができます。

3. Google へのコミッション

デバイスを制御し、同じファブリック内でデバイス同士が通信できるようにするには、コミッショナー(この場合は、このサンプル アプリケーションである Matter 用 Google Home サンプルアプリ)のコマンド処理が必要です。

Matter のコミッショニングに関する次の概念を理解することが重要です。

  • ファブリックによって、デバイス同士が通信できるようになります。
  • ファブリックは、共有された一意の認証情報のセットを保持します。
  • エコシステムは、信頼できるルート証明書の発行、ファブリック ID の割り当て、一意のノード ID の割り当てを行います。エコシステムとは、コミッショナーのバックエンド サービスです。たとえば、Google Home エコシステムのホームグラフなどです。
  • デバイスは複数のファブリックにコミッショニングできます(マルチ管理機能)。

デバイスのコミッショニングには、CommissioningClient API を使用する必要があります。.commissionDevice() を呼び出すと IntentSender が返されます。これにより、Google Play 開発者サービスで適切なアクティビティが起動します。

interface CommissioningClient {
  Task<IntentSender> commissionDevice(CommissioningRequest request);
}

次のセクションでは、デバイスを Google ファブリックにコミッショニングするために必要な最小限のコードについて説明します。

ステップ 1: アクティビティ ランチャー

CommissioningClient からの IntentSender を処理するには、ActivityResultLauncher を使用します。

val commissioningLauncher = registerForActivityResult(
    StartIntentSenderForResult()
) { result: ActivityResult ->
    if (result.resultCode == RESULT_OK) {
        Timber.d(TAG, "Commissioning succeeded.")
    } else {
        Timber.d(TAG, "Commissioning failed. " + result.resultCode)
    }
}

ステップ 2: コミッショニング機能

ここでは、 CommissioningClient API を使用してデバイスを Google ファブリックにコミッショニングする基本的な例を示します。

  1. コミッショニング プロセスは commissionDevice() 関数から始まります。まず、CommissioningRequest が定義されます。このデフォルト設定では、デバイスはローカル Android ファブリックにのみコミッショニングされます。
  2. Matter は、Home Mobile SDK のエントリ ポイントです。次の呼び出しで、.getCommissioningClientthis(Activity)によって CommissioningClient を取得します。
  3. .commissionDevice()CommissioningRequest を受け入れます。
  4. 最後に、.addOnSuccessListener が呼び出され、CommissioningResult を処理し、Google Play 開発者サービス(GPS)のコミッション デバイス アクティビティが開始されます。
private fun commissionDevice() {
    val request: CommissioningRequest = CommissioningRequest.builder().build()
    Matter.getCommissioningClient(this)
        .commissionDevice(request)
        .addOnSuccessListener { result ->
            commissioningLauncher.launch(IntentSenderRequest.Builder(result).build())
        }
}

Android の設定を介してローカル Android ファブリックを活用することで、デバイスを他のファブリックにコミッショニングするプロセスを簡素化できます。

次に、デバイスを開発ファブリックにコミッショニングする方法を学びます。

コミッショニング プロセスにおけるユーザー インターフェースの概要については、Matter 向け Google Home サンプルアプリのガイドをご覧ください。

4. 開発ファブリックへのコミッション

デバイスは複数のファブリックにコミッショニングできます。信頼できるペア設定を管理するために、デバイスはさまざまな FabricInfo メンバーを含む FabricTable を保存します。次に例を示します。

  • ファブリック ID
  • ファブリックによってデバイスに割り当てられたノード ID
  • ベンダー ID
  • ファブリック ID
  • デバイスの操作認証情報

管理ドメイン マネージャー(ADM)がファブリック認証情報を定義します。前のシナリオでは、Google Play 開発者サービスは、信頼できるルート認証局(CA)として機能するエコシステムです。デバイスをローカル Android ファブリックにコミッショニングすると、すべてのデバイスに同じファブリック認証情報のセットと同じ CA のセットが含まれます。

カスタム コミッショニング サービス

ローカル Android ファブリックにコミッショニングするために、デフォルトのパラメータを使用して、 CommissioningClient API で CommissioningRequest をビルドしました。

val request: CommissioningRequest = CommissioningRequest.builder().build()

アプリから新しいデバイスの制御と管理を行う場合は、ローカルの開発ファブリックを作成し、デバイスをコミッショニングするための運用認証情報を取得する必要があります。このシナリオでは、アプリは、デバイスに適切なノード認証情報を割り当てる、ユニークで独立したエコシステムとなります。

カスタム サービスを CommissioningRequest に渡すことで、デバイスを独自のファブリックにコミッショニングすることを Home Mobile SDK に伝えることができます。

class CommissioningRequest {
  static CommissioningRequest.Builder builder();

  class Builder {
    Builder setCommissioningService(@Nullable ComponentName commissioningService);

    CommissioningRequest build();
  }
}

次のステップでは、カスタム サービスを使用するように commissionDevice() 関数を変更します。また、Home フラグメントにアクティビティ ランチャーを追加し、LiveData オブジェクトを使用して API フローを管理します。

ステップ 1: GPS アクティビティ ランチャーを作成する

まず、 CommissioningClient API の IntentSender を処理するアクティビティ ランチャーを作成します。

  1. java/screens/home/ フォルダ内の HomeScreen を開きます。
  2. // CODELAB: commissionDeviceLauncher definition コメントを次のコードに置き換えて、コミッショニング アクティビティの結果を登録して処理します。
    val commissionDeviceLauncher =
      rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartIntentSenderForResult()
      ) { result ->
        // Commission Device Step 5.
        // The Commission Device activity in GPS (step 4) has completed.
        val resultCode = result.resultCode
        if (resultCode == Activity.RESULT_OK) {
          Timber.d("CommissionDevice: Success")
          // We let the ViewModel know that GPS commissioning has completed successfully.
          // The ViewModel knows that we still need to capture the device name and will\
          // update UI state to trigger the NewDeviceAlertDialog.
          homeViewModel.gpsCommissioningDeviceSucceeded(result)
        } else {
          homeViewModel.commissionDeviceFailed(resultCode)
        }
      }
    

ステップ 2: コミッション デバイスのアクションをトリガーする

このステップでは、ユーザーがホーム画面の右下にある [+] ボタンをクリックして、「Commission Device」アクションをトリガーします。その後、commissionDevice() に対して呼び出しが行われます。

val onCommissionDevice = {
  ...
  commissionDevice(activity!!.applicationContext, commissionDeviceLauncher)
}

ステップ 3: API を呼び出す

  1. 引き続き HomeScreen.ktjava/screens/home/ フォルダにあります。
  2. // CODELAB: commissionDevice コメントを次の commissionDeviceRequest に置き換えます。setCommissioningService は、コールバック関数で返される CommissioningService インスタンスに AppCommissioningService をバインドします。カスタム サービスを渡すと、Home Mobile SDK はまずデバイスを Android のローカル ファブリックにコミッショニングし、オンボーディング ペイロードを AppCommissioningService に返します。
    val commissionDeviceRequest =
        CommissioningRequest.builder()
            .setCommissioningService(ComponentName(
                context, AppCommissioningService::class.java))
            .build()
    
  3. .getCommissioningClient() を呼び出してから、.commissionDevice() を呼び出します。
Matter.getCommissioningClient(context)
    .commissionDevice(commissionDeviceRequest)

commissionDevice 関数を完成させるために、addOnSuccessListeneraddOnFailureListener を追加します。

    .addOnSuccessListener { result ->
      commissionDeviceLauncher.launch(IntentSenderRequest.Builder(result).build())
    }
    .addOnFailureListener { error ->
      Timber.e(error)
    }

5. CommissioningService を作成する

commissionDevice() 関数で、CommissioningClient API から CommissioningService を取得するようリクエストしました。このフローでは、CommissioningClient API はまずデバイスをローカル Android ファブリックにコミッショニングし、次に CommissioningRequestMetadata オブジェクトを含むコールバックを返します。

public interface CommissioningService {
interface Callback {
    void onCommissioningRequested(CommissioningRequestMetadata metadata);
  }
}

次に、 CommissioningService.Callback を継承し、デバイスのコミッショニングに必要な機能をサンプルアプリに提供する必要があります。基本的な CommissioningService の実装の例を次に示します。

class MatterCommissioningService : Service(), CommissioningService.Callback {
   private val commissioningServiceDelegate =
     CommissioningService.Builder(this)
       .setCallback(this)
       .build()

   override fun onBind(intent: Intent) = commissioningServiceDelegate.asBinder()

   override fun onCommissioningRequested(metadata: CommissioningRequestMetadata) {
     // perform commissioning

     commissioningServiceDelegate
       .sendCommissioningComplete(CommissioningCompleteMetadata.builder().build())
   }
 }

ステップ 1: カスタムの AppCommissioningService を確認する

簡単に始められるように、カスタムの CommissioningService の基本クラス構造はすでに定義されています。ここでは、このサービスの機能の概要を簡単に説明します。説明を進めるには、java/commissioningAppCommissioningService を開いてください。

Home Mobile SDK API 用に以下のインポートを追加しました。

import com.google.android.gms.home.matter.commissioning.CommissioningCompleteMetadata
import com.google.android.gms.home.matter.commissioning.CommissioningRequestMetadata
import com.google.android.gms.home.matter.commissioning.CommissioningService

AppCommissioningService には、Matter リポジトリ(connectedhomeipのライブラリも含まれます。

import com.google.home_sample_app_for_matter.chip.ChipClient

さらに、このサービスには、HiltKotlin コルーチンをサポートするためのインポートが含まれています。

次に、コンストラクタを作成して、commissioningServiceDelegate などをセットアップします。これは、コミッショニングが完了したときに Google Play 開発者サービスに通知するために使用されます。

private lateinit var commissioningServiceDelegate: CommissioningService
...
commissioningServiceDelegate = CommissioningService.Builder(this).setCallback(this).build()

次に、コミッショニング関数を追加します。

ステップ 2: onCommissioningRequested をオーバーライドする

デバイスをアプリの開発ファブリックにコミッショニングするには、次の手順を行います。

  1. java/commissioningAppCommissioningServiceを開きます。
  2. onCommissioningRequested() 関数を見つけます。CommissioningRequestMetadata を出力するログメッセージが用意されています。// CODELAB: onCommissioningRequested() コメントを置き換えて serviceScope コルーチンを開始し、deviceId を取得します。
    // Perform commissioning on custom fabric for the sample app.
    serviceScope.launch {
      val deviceId = devicesRepository.incrementAndReturnLastDeviceId()
    
  3. コミッショニングを実行します。このステップでは、CommissioningRequestMetadata オブジェクトで返されたデバイス情報を渡すことができます。ChipClient はこのメタデータ情報を使用して、GHSA for Matter アプリとお使いのデバイスの間に安全なチャネルを作成します。
    try {
      Timber.d(
          "Commissioning: App fabric -> ChipClient.establishPaseConnection(): deviceId [${deviceId}]")
      chipClient.awaitEstablishPaseConnection(
          deviceId,
          metadata.networkLocation.ipAddress.hostAddress!!,
          metadata.networkLocation.port,
          metadata.passcode)
      Timber.d(
          "Commissioning: App fabric -> ChipClient.commissionDevice(): deviceId [${deviceId}]")
      chipClient.awaitCommissionDevice(deviceId, null)
    } catch (e: Exception) {
      Timber.e(e, "onCommissioningRequested() failed")
      // No way to determine whether this was ATTESTATION_FAILED or DEVICE_UNREACHABLE.
      commissioningServiceDelegate
          .sendCommissioningError(CommissioningError.OTHER)
          .addOnSuccessListener {
            Timber.d(
                "Commissioning: commissioningServiceDelegate.sendCommissioningError() succeeded")
          }
          .addOnFailureListener { e2 ->
            Timber.e(e2, "Commissioning: commissioningServiceDelegate.sendCommissioningError() failed")
          }
      return@launch
    }
    
  4. commissioningServiceDelegate を使用して、コミッショニングが完了したことを Google Play 開発者サービスに通知します。.sendCommissioningComplete() で、CommissioningCompleteMetadata を渡します。
    commissioningServiceDelegate
        .sendCommissioningComplete(
            CommissioningCompleteMetadata.builder().setToken(deviceId.toString()).build())
        .addOnSuccessListener {
          Timber.d("Commissioning: commissioningServiceDelegate.sendCommissioningComplete() succeeded")
        }
        .addOnFailureListener { e ->
          Timber.e(e, "Commissioning: commissioningServiceDelegate.sendCommissioningComplete() failed")
        }
    

アプリを実行する

ローカル ファブリックにコミッショニングするために必要なコードがすべて揃ったので、次はテストです。Android デバイスを選択してアプリを実行します。ホーム画面で [Add Device] をタップし、デバイスのコミッショニング手順を完了します。

コミッショニングが完了すると、デバイスは 2 つのファブリック(ローカル Android ファブリックとローカル開発ファブリック)に参加します。各ファブリックには、独自の認証情報セットと一意の 64 ビット ファブリック ID があります。

6. デバイスを操作する

開発ファブリックにコミッショニングすると、Matter リポジトリ(connectedhomeipのライブラリを使用して、サンプルアプリからデバイスを制御できます。

デバイスのクラスタに簡単にアクセスしてコマンドを送信できるように、いくつかのヘルパークラスを作成しました。詳しくは、java/clustersClustersHelper を開いてください。このシングルトン ヘルパーは、次のライブラリをインポートしてデバイス情報にアクセスします。

import chip.devicecontroller.ChipClusters
import chip.devicecontroller.ChipStructs

このクラスを使用してデバイスのオン/オフ クラスタを取得し、.toggle を呼び出すことができます。

suspend fun toggleDeviceStateOnOffCluster(deviceId: Long, endpoint: Int) {
  Timber.d("toggleDeviceStateOnOffCluster())")
  val connectedDevicePtr =
      try {
        chipClient.getConnectedDevicePointer(deviceId)
      } catch (e: IllegalStateException) {
        Timber.e("Can't get connectedDevicePointer.")
        return
      }
  return suspendCoroutine { continuation ->
    getOnOffClusterForDevice(connectedDevicePtr, endpoint)
        .toggle(
            object : ChipClusters.DefaultClusterCallback {
              override fun onSuccess() {
                continuation.resume(Unit)
              }
              override fun onError(ex: Exception) {
                Timber.e("readOnOffAttribute command failure: $ex")
                continuation.resumeWithException(ex)
              }
            })
  }
}

デバイスを切り替える

デバイスのコミッショニングが完了すると、CommissioningResult で返されたペイロードが DataStore に追加されます。これにより、コマンドの送信に使用できるデバイス情報にアプリがアクセスできるようになります。

Matter アプリはイベント ドリブンです。Matter スタックが初期化されると、クラスタ サービスは受信メッセージをリッスンします。デバイスがコミッショニングされると、Matter クライアントは、デバイスのコミッショニング中に確立された安全な運用チャネルを介してコマンドを送信します。

デバイス上で、パケットが検証、復号された後、コールバックでディスパッチされます。コールバック関数には、attributePath からアクセスできる EndpointId、ClusterId、AttributeId が含まれます。たとえば、次のコードは Matter 対応デバイスに実装できます。

void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t mask, uint8_t type,
                                       uint16_t size, uint8_t * value)
{
    // handle callback
    ClusterId clusterId     = attributePath.mClusterId;
    AttributeId attributeId = attributePath.mAttributeId;
}

次の手順では、Matter SDK と ClustersHelper を使用してデバイスを切り替えます。

  1. java/screens/deviceDeviceViewModel にアクセスしてください。
  2. updateDeviceStateOn 関数を見つけます。
  3. // CODELAB: toggle のコメントを clustersHelper を呼び出すコードに置き換えてから、デバイス リポジトリを更新します。
    Timber.d("Handling real device")
        try {
          clustersHelper.setOnOffDeviceStateOnOffCluster(deviceUiModel.device.deviceId, isOn, 1)
          devicesStateRepository.updateDeviceState(deviceUiModel.device.deviceId, true, isOn)
        } catch (e: Throwable) {
          Timber.e("Failed setting on/off state")
        }
    

この関数は DeviceScreen から呼び出されます。

// On/Off Switch click.
val onOnOffClick: (value: Boolean) -> Unit = { value ->
  deviceViewModel.updateDeviceStateOn(deviceUiModel!!, value)
}

アプリを実行する

アプリを実行して更新を再読み込みします。ホーム画面で、デバイスのオンとオフを切り替えます。

7. 他のエコシステムとのデバイスの共有

Matter の仕様では、デバイスの共有はマルチ管理フローと呼ばれています。

これまでのステップで、Home Mobile SDK を使用すると、デバイスをローカル Android ファブリックとサンプルアプリの開発ファブリックにコミッショニングできることを学びました。これは、デバイスを複数のファブリックにコミッショニングできるマルチ管理フローの例です。

今度は、さらに多くのファブリックでデバイスを共有したい場合があります。特に、この世帯で、ユーザーがアプリとプラットフォームについて好みがある場合はなおさらです。

Home Mobile SDK は、ShareDeviceRequest API でこの機能を提供し、次のことを行えます。

  1. デバイスの一時的なコミッショニング期間を開きます。
  2. デバイスの状態を変更し、別のファブリックにコミッショニングできるようにします。
  3. 他のアプリやエコシステムからデバイスを操作。

次のステップでは、Home Mobile SDK を使用してデバイスを共有します。

ステップ 1: GPS アクティビティ ランチャーを作成する

開発ファブリックにコミッショニングしたときに作成したコミッショニング アクティビティ ランチャーと同様に、commitingClient API からの IntentSender を処理するためにデバイス アクティビティ ランチャーを作成しました。

  1. java/screens/device/ フォルダ内の DeviceScreen を開きます。
  2. // CODELAB: shareDeviceLauncher definition コメントを次のコードに置き換えて、.shareDevice() Activity の結果を登録して処理します。
    val shareDeviceLauncher = rememberLauncherForActivityResult(
      contract = ActivityResultContracts.StartIntentSenderForResult()
    ) { result ->
      // Commission Device Step 5.
      // The Share Device activity in GPS (step 4) has completed.
      val resultCode = result.resultCode
      if (resultCode == Activity.RESULT_OK) {
        deviceViewModel.shareDeviceSucceeded()
      } else {
        deviceViewModel.shareDeviceFailed(resultCode)
      }
    }
    

ステップ 2: デバイスの共有アクションをトリガーする

このステップでは、ユーザーがデバイスの画面で [Share] ボタンをクリックして、[Share Device] アクションをトリガーします。次に、deviceViewModel が呼び出され、デバイス共有のペア設定ウィンドウが開きます。

// Share Device button click.
val onShareDevice: () -> Unit = {
 deviceViewModel.openPairingWindow(deviceUiModel!!.device.deviceId)
}

ペア設定ウィンドウが正常に開くと、deviceViewModel がその旨を UI に伝えます。ViewModel と UI 間の通信は、StateFlow オブジェクトを介して行われます。

// Communicate to the UI that the pairing window is open.
// UI can then launch the GPS activity for device sharing.
_pairingWindowOpenForDeviceSharing.value = true

StateFlow オブジェクトの変更に応じて、DeviceScreen は次の呼び出しを行います。

shareDevice(activity!!.applicationContext, shareDeviceLauncher, deviceViewModel)

ステップ 3: API を呼び出す

次に、デバイスの共有タスクを開始します。

  1. java/screens/device/ フォルダ内の DeviceScreen.kt を開きます。
  2. shareDevice() 関数を見つけます。// CODELAB: shareDevice コメントを ShareDeviceRequest に置き換えます。DeviceDescriptor は、ベンダー ID、プロダクト ID、deviceType など、デバイスに関する特定の情報を提供します。この例では、値をハードコードしています。
    val shareDeviceRequest =
      ShareDeviceRequest.builder()
        .setDeviceDescriptor(DeviceDescriptor.builder().build())
        .setDeviceName("GHSAFM temp device name")
    
  3. CommissioningWindowパラメータを設定します。
        .setCommissioningWindow(
            CommissioningWindow.builder()
                .setDiscriminator(Discriminator.forLongValue(DISCRIMINATOR))
                .setPasscode(SETUP_PIN_CODE)
                .setWindowOpenMillis(SystemClock.elapsedRealtime())
                .setDurationSeconds(OPEN_COMMISSIONING_WINDOW_DURATION_SECONDS.toLong())
                .build())
        .build()
    
  4. .getCommissioningClient() を呼び出します。今回は .shareDevice() API を使用します。
    Matter.getCommissioningClient(context)
        .shareDevice(shareDeviceRequest)
    

commissioningClient.shareDevice() API の成功コールバックは、Google Play 開発者サービスでデバイス共有アクティビティを起動する際に使用する IntentSender を提供します。

  1. shareDevice 関数を完成させるために、addOnSuccessListeneraddOnFailureListener を追加します。成功すると、shareDeviceLauncherlaunch が呼び出され、デバイス共有用の GPS アクティビティが起動します。
        .addOnSuccessListener { result ->
          Timber.d("ShareDevice: Success getting the IntentSender: result [${result}]")
          shareDeviceLauncher.launch(IntentSenderRequest.Builder(result).build())
        }
        .addOnFailureListener { error ->
          Timber.e(error)
          deviceViewModel.showMsgDialog("Share device failed", error.toString())
        }
    

アプリを実行する

Matter デバイスを他のエコシステムと共有するには、Android デバイスに別のプラットフォームをインストールする必要があります。ターゲット コミッショナーとして使用できるサンプルアプリの別のインスタンスを作成しました。

Android デバイスに対象のコミッショナーをインストールしたら、Matter デバイスを共有できることを確認します。対象となるコミッショナー アプリは GHSAFM-TC というラベルが付けられています。

デバイスが次の 3 つのファブリックに参加できるようになりました。

  1. ローカル Android ファブリック。
  2. 開発ファブリック(このアプリ)。
  3. デバイスを共有した 3 つ目のファブリックです。

8. 次のステップ

完了

これで、この Codelab は終了です。Home Mobile SDK を使用してデバイスのコミッショニングと共有を行う方法を学びました。

サンプルアプリで問題が発生した場合は、次の手順を行って環境を確認してください。

サンプルアプリの使用に関する質問がある場合や、コードのバグを見つけた場合は、GitHub リポジトリの Issue Tracker に問題を送信できます。

技術的な質問について Google から正式なガイダンスを得るには、スマートホーム デベロッパー フォーラムをご利用ください。

コミュニティからテクニカル サポートを受けるには、Stack Overflow で google-smart-home タグを使用します。