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

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

1. ようこそ

Matter は、IoT 規格の統合を目的に、Google Home、Zigbee、Bluetooth Mesh、Z-Wave などのさまざまなエコシステムでスマートホーム デバイスを接続しています。

モバイル デバイスは、スマートホーム デバイスの中核となる操作ポイントです。Matter デバイスをサポートする独自の Android アプリを作成したい場合は、すぐに使用を開始できます。

Matter 用 Google Home サンプルアプリ(Matter 用 GHSA)には、Home Mobile SDK API が紹介されており、ユーザーはデバイスを委託して共有することができます。サンプルアプリを学習ツールとして使用し、Matter の主なコンセプトを理解したり、Matter デバイスとのやり取りをデバッグしたりトラブルシューティングしたりするためのツールも利用できます。

演習内容

この Codelab では、サンプルアプリのソースコードをダウンロードし、Home Mobile SDK を使用してデバイスを委託および共有する方法を学びます。コミッション ライブラリとクラスタ ライブラリの使用方法は、Matter リポジトリ(connectedhomeipでも学習できます。

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

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

必要なもの

開始する前に、次の手順を完了してください。

サンプルアプリでデバイスをコミッションして制御するために、Google Nest Hub(第 2 世代)などのハブは必要ありません。

2. 設定する

サンプルアプリの GitHub リポジトリには、Matter リポジトリ(connectedhomeipのサードパーティ ライブラリが含まれています。これらのネイティブ ライブラリは 50 MB を超えており、Git Large Storage(LFS)を使用する必要があります。

Codelab スターター アプリは codelab ブランチにあります。Codelab ソースコードの使用を開始するには、ZIP ファイルをダウンロードします。この ZIP には、Git LFS を必要とせずに Matter SDK ネイティブ ライブラリが含まれています。

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

Codelab のバージョン

codelab ブランチにはサンプルアプリの 1.2.2 リリースのタグが付けられています。各手順を進めながら更新内容を比較するには、このリリースの完全なソースコードをダウンロードしてください。

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

依存関係

デバイスの共有とコミッションに必要なソースコードについてご説明しますが、始める前に、次の依存関係を認識しておくとよいでしょう。

  • Home Mobile SDK
    implementation 'com.google.android.gms:play-services-home:16.0.0'
    
  • Matter SDK ライブラリ。
    // Native libs
    implementation fileTree(dir: "third_party/connectedhomeip/libs", include: ["*.jar", "*.so"])
    
  • マテリアル デザイン詳しくは、MDC-103 Android: 色、エレベーション、タイプ(Kotlin)によるマテリアル テーマ設定マテリアル テーマビルダーをご覧ください。
    implementation 'com.google.android.material:material:1.5.0'
    
  • アプリデータの永続化に使用する Proto DataStore。Datastore リポジトリとシリアライザは、デバイスのスキーマやユーザー設定を含む java/data に保存されます。DataStore の詳細については、Proto DataStore を使用するをご覧ください。
    implementation "androidx.datastore:datastore:$dataStoreVersion"
    implementation 'androidx.datastore:datastore-core:1.0.0'
    implementation 'com.google.protobuf:protobuf-javalite:3.18.0'
    
  • Hilt: データを保持し、依存関係の注入をサポートします。
    kapt 'com.google.dagger:hilt-compiler:2.41'
    implementation 'com.google.dagger:hilt-android:2.41'
    

ソースコード

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

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

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

各ファイルには、次のようなコードブロックが追加されます。

// CODELAB: add commissioningFunction()

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

3.Google への委託

デバイスを制御して同じファブリック内で相互に通信できるようにするには、コミッショナーの委託を受ける必要があります。このサンプルでは、Matter 用の Google Home サンプルアプリをサンプルアプリとして提供しています。

Matter のコミッションについて、次のコンセプトを理解しておくことが重要です。

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

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

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

次のセクションでは、デバイスを Google Fabric に委託するために必要な最小限のコードについて説明します。

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

CommissioningClientIntentSender を処理するには、ActivityResultLauncher を使用します。

private lateinit var commissioningLauncher: ActivityResultLauncher<IntentSenderRequest>
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 Fabric に委託する基本的な例を示します。

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

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

デバイスをカスタム ファブリックに委託することを Home Mobile SDK に通知するには、カスタム サービスを CommissioningRequest に渡します。

class CommissioningRequest {
  static CommissioningRequest.Builder builder();

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

    CommissioningRequest build();
  }
}

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

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

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

  1. java/screens/home/ フォルダで HomeFragment を開きます。
  2. // CODELAB: commissionDeviceLauncher declaration コメントは次の宣言に置き換えます。
    // The ActivityResult launcher that launches the "commissionDevice" activity in Google Play
    // Services.
    private lateinit var commissionDeviceLauncher: ActivityResultLauncher<IntentSenderRequest>
    
  3. コミッション アクティビティの結果を登録して処理するには、// CODELAB: commissionDeviceLauncher definition コメントを次のコードに置き換えます。
    commissionDeviceLauncher =
        registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result ->
          // Commission Device Step 5.
          // The Commission Device activity in GPS has completed.
          val resultCode = result.resultCode
          if (resultCode == Activity.RESULT_OK) {
            Timber.d("CommissionDevice: Success")
            // We now need to capture the device information for the app's fabric.
            // Once this completes, a call is made to the viewModel to persist the information
            // about that device in the app.
            showNewDeviceAlertDialog(result)
          } else {
            viewModel.commissionDeviceFailed(resultCode)
          }
        }    ```
    
    

ステップ 2: LiveData オブジェクトを作成する

.commissionDevice() API の成功コールバックは、Google Play 開発者サービスでコミッション デバイス アクティビティの起動に使用される IntentSender を提供します。HomeViewModel で、この API 呼び出しの結果をレポートする 2 つの LiveData オブジェクトを作成します。

  • commissionDeviceStatus: TaskStatus をトラッキングします。
  • commissionDeviceIntentSender: .commissionDevice() 呼び出しの結果を処理します。この LiveData オブジェクトにより、作成したばかりの ActivityLauncher が起動し、GPS コミッション デバイス アクティビティがユーザーに表示されます。
  1. private fun setupObservers() で、// CODELAB: commissionDeviceStatus コメントを次のオブザーバーに置き換えます。
    // The current status of the share device action.
    viewModel.commissionDeviceStatus.observe(viewLifecycleOwner) { status ->
      Timber.d("commissionDeviceStatus.observe: status [${status}]")
    }
    
  2. 次に、// CODELAB: commissionDeviceIntentSender コメントを次のオブザーバーに置き換えます。
    viewModel.commissionDeviceIntentSender.observe(viewLifecycleOwner) { sender ->
      Timber.d(
          "commissionDeviceIntentSender.observe is called with [${intentSenderToString(sender)}]")
      if (sender != null) {
        // Commission Device Step 4: Launch the activity described in the IntentSender that
        // was returned in Step 3 (where the viewModel calls the GPS API to commission
        // the device).
        Timber.d("CommissionDevice: Launch GPS activity to commission device")
        commissionDeviceLauncher.launch(IntentSenderRequest.Builder(sender).build())
        viewModel.consumeCommissionDeviceIntentSender()
      }
    }
    

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

API フローを処理するコードを作成したので、次は API を呼び出し、カスタム サービス(次のステップで定義します)を渡して、LiveData オブジェクトに投稿します。

  1. java/screens/home/ フォルダで HomeViewModel.kt を開きます。
  2. // CODELAB: commissionDevice コメントは次の commissionDeviceRequest に置き換えます。setCommissioningService は、コールバック関数で返される CommissioningService インスタンスに AppCommissioningService をバインドします。カスタム サービスを渡すと、Home Mobile SDK はまずデバイスを Google ファブリックに委託してから、オンボーディング ペイロードを AppCommissioningService に送り返します。
    fun commissionDevice(context: Context) {
      _commissionDeviceStatus.postValue(TaskStatus.InProgress)
    
      val commissionDeviceRequest =
          CommissioningRequest.builder()
              .setCommissioningService(ComponentName(context, AppCommissioningService::class.java))
              .build()
    
  3. .getCommissioningClient() を呼び出してから、.commissionDevice() を呼び出します。
    Matter.getCommissioningClient(context)
        .commissionDevice(commissionDeviceRequest)
    

commissionDevice 関数を完成させるには、addOnSuccessListeneraddOnFailureListener を追加し、LiveData オブジェクトに投稿します。

      .addOnSuccessListener { result ->
        // Communication with fragment is via livedata
        _commissionDeviceIntentSender.postValue(result)
      }
      .addOnFailureListener { error ->
        Timber.e(error)
        _commissionDeviceStatus.postValue(
          TaskStatus.Failed("Failed to to get the IntentSender.", error)
      }
}

構成の使用後に送信者を再度受信しないように、送信者の使用後は consumeCommissionDeviceIntentSender() を呼び出してください。

  /**
   * Consumes the value in [_commissionDeviceIntentSender] and sets it back to null. Needs to be
   * called to avoid re-processing the IntentSender after a configuration change (where the LiveData
   * is re-posted).
   */
  fun consumeCommissionDeviceIntentSender() {
    _commissionDeviceIntentSender.postValue(null)
  }

5. CommissioningService を作成する

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

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

CommissioningService.Callback を継承し、サンプルアプリにデバイスをコミッションするために必要な機能を提供する必要があります。以下は、基本的なコミッション サービス実装の例です。

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 を確認する

簡単に始められるよう、カスタムのコミッション サービスの基本的なクラス構造を定義しました。ここでは、サービスの機能を簡単に説明します。続行するには、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 コルーチンをサポートするインポートが含まれています。

次に、コンストラクタを作成し、いくつかの項目を設定します。これらを使用して、Google はコミッションの完了時に Google Play 開発者サービスに通知します。commissioningServiceDelegate

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: このメタデータ情報を使用して、Matter アプリの GHSA とデバイスの間に安全なチャネルを作成します。
    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)
    
  4. commissioningServiceDelegate を使用して、Google Play 開発者サービスに委託が完了したことを知らせます。.sendCommissioningComplete()CommissioningCompleteMetadata を渡します。
      Timber.d("Commissioning: Calling commissioningServiceDelegate.sendCommissioningComplete()")
      commissioningServiceDelegate
          .sendCommissioningComplete(
              CommissioningCompleteMetadata.builder().setToken(deviceId.toString()).build())
          .addOnSuccessListener {
              Timber.d("Commissioning: OnSuccess for commissioningServiceDelegate.sendCommissioningComplete()")
          }
          .addOnFailureListener { ex -> 
            Timber.e(ex, "Commissioning: Failed to send commissioning complete.", ex)
          }
    }
    

アプリを実行する

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

コミッションが完了すると、デバイスはローカル Android ファブリックとローカル開発ファブリックの 2 つのファブリックに参加するようになります。各ファブリックには独自の認証情報のセットと一意の 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)
              }
            })
  }
}

デバイスを切り替える

デバイスを commit すると、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")
        }
    

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

// Change the on/off state of the device
binding.onoffSwitch.setOnClickListener {
  val isOn = binding.onoffSwitch.isChecked
  viewModel.updateDeviceStateOn(selectedDeviceViewModel.selectedDeviceLiveData.value!!, isOn)
}

アプリを実行する

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

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

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

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

さらに多くのファブリックでデバイスを共有することをおすすめします。特に、アプリケーションやプラットフォームに関してユーザーが好みを持っている家庭ではなおさらです。

Home Mobile SDK は、ShareDeviceRequest API でこの機能を提供しており、これにより次のことが可能になります。

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

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

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

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

  1. java/screens/device/ フォルダで DeviceFragment を開きます。
  2. // CODELAB: shareDeviceLauncher definition コメントを次のコードに置き換えて、.shareDevice() アクティビティの結果を登録して処理します。
    shareDeviceLauncher =
        registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result ->
          // Share Device Step 5.
          // The Share Device activity in GPS (step 4) has completed.
          val resultCode = result.resultCode
          if (resultCode == RESULT_OK) {
            Timber.d("ShareDevice: Success")
            viewModel.shareDeviceSucceeded(selectedDeviceViewModel.selectedDeviceLiveData.value!!)
          } else {
            viewModel.shareDeviceFailed(
                selectedDeviceViewModel.selectedDeviceLiveData.value!!, resultCode)
          }
        }
    

ステップ 2: LiveData オブジェクトを確認する

.shareDevice() API の成功コールバックは、Google Play 開発者サービスで「デバイスを共有」アクティビティを起動するための IntentSender を提供します。DeviceViewModel で、この API 呼び出しの結果を報告するための 2 つの LiveData オブジェクトを作成しました。

  • _shareDeviceStatus: TaskStatus をトラッキングします。
    // The current status of the share device action.
    viewModel.shareDeviceStatus.observe(viewLifecycleOwner) { status ->
      val isButtonEnabled = status !is InProgress
      updateShareDeviceButton(isButtonEnabled)
      if (status is TaskStatus.Failed) {
        showAlertDialog(errorAlertDialog, status.message, status.cause!!.toString())
      }
    }
    
  • _shareDeviceIntentSender: .sharedevice() 呼び出しの結果を処理します。

viewModel.shareDeviceIntentSender.observe(viewLifecycleOwner) {Sender -> Timber.d("shareDeviceIntentSender.observe is called with [${intentSenderToString(sender)}] if ((sender != null) { // デバイスを共有ステップ 4: // ステップ 3 で返された // しており、viewModel がコミッションされたデバイスに API を呼び出した場合。Timber.d("ShareDevice: Launch GPS activity to share device") ShareDeviceLauncher.launch(IntentSenderRequest.Builder(sender).build()) viewModel.consumeShareDeviceIntentSender() } } ``

次のステップでは、これらの LiveData オブジェクトを .shareDevice() API 呼び出しで使用します。

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

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

  1. java/screens/device/ フォルダで DeviceViewModel.kt を開きます。
  2. shareDevice() 関数を見つけます。// CODELAB: shareDevice コメントを ShareDeviceRequest に置き換えます。DeviceDescriptor は、ベンダー ID、プロダクト ID、deviceType など、デバイスに関する特定の情報を提供します。この例では、値をハードコードしています。
      Timber.d("ShareDevice: Setting up the IntentSender")
      val shareDeviceRequest =
          ShareDeviceRequest.builder()
              .setDeviceDescriptor(DeviceDescriptor.builder().build())
              .setDeviceName("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 を使用します。commissioningClient.shareDevice() API の成功コールバックは、Google Play 開発者サービスで「デバイスを共有」アクティビティを起動する際に使用する IntentSender を提供します。
    Matter.getCommissioningClient(activity)
        .shareDevice(shareDeviceRequest)
    
  5. shareDevice 関数を完成させるには、addOnSuccessListeneraddOnFailureListener を追加し、LiveData オブジェクトに投稿します。
          .addOnSuccessListener { result ->
            Timber.d("ShareDevice: Success getting the IntentSender: result [${result}]")
            // Communication with fragment is via livedata
            _backgroundWorkAlertDialogAction.postValue(BackgroundWorkAlertDialogAction.Hide)
            _shareDeviceIntentSender.postValue(result)
          }
          .addOnFailureListener { error ->
            Timber.e(error)
            _backgroundWorkAlertDialogAction.postValue(BackgroundWorkAlertDialogAction.Hide)
            _shareDeviceStatus.postValue(
                TaskStatus.Failed("Setting up the IntentSender failed", error))
          }
    

構成の使用後に送信者を再度受信しないように、送信者の使用後は consumeShareDeviceIntentSender を呼び出してください。

  /**
   * Consumes the value in [_shareDeviceIntentSender] and sets it back to null. Needs to be called
   * to avoid re-processing an IntentSender after a configuration change where the LiveData is
   * re-posted.
   */
  fun consumeShareDeviceIntentSender() {
    _shareDeviceIntentSender.postValue(null)
  }

アプリを実行する

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

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

お使いのデバイスは、以下の 3 つのファブリックに参加できます。

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

8. 次のステップ

完了

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

サンプルアプリに問題がある場合は、以下の手順で環境の確認を行ってください。

サンプルアプリの使用についてご不明な点がある場合やコードのバグを見つけた場合は、GitHub リポジトリで Issue Tracker に問題を報告できます。

技術的な質問について Google からの公式ガイダンスを入手するには、スマートホーム デベロッパー フォーラムを使用してください。

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