IMPORTANT: You must be part of the Matter Private Beta Program to start developing Matter devices and apps in the Google Home Developer Console. Apply now

Thread Network SDK für Android

Das Thread Network SDK bietet Funktionen, die einem digitalen Schlüsselbund ähneln, sodass deine Android-Apps Thread-Netzwerkanmeldedaten mit Google Play-Diensten teilen können. Dadurch können Ihre Apps jedes Thread-Gerät von jedem Smart-Home-System aus einrichten, ohne dass Anmeldedaten und Nutzerdaten direkt offengelegt werden.

Mit nur wenigen API-Aufrufen können Sie:

  1. Bevorzugte Anmeldedaten für Thread-Netzwerk von Google Play-Diensten anfordern.
  2. Richte neue Border-Router ein und füge deinen Google Play-Diensten deine Anmeldedaten für das Thread-Netzwerk hinzu.
  3. Wenn Sie bereits Border-Router im Feld haben, können Sie prüfen, ob sich Ihre Border-Router im bevorzugten Netzwerk befinden, und sie bei Bedarf migrieren.

Es gibt mehrere Aspekte, die Nutzer und Entwickler berücksichtigen müssen. In diesem Leitfaden werden die meisten dieser Tools sowie weitere wichtige Funktionen und empfohlene Nutzung beschrieben.

Wichtige Begriffe und API-Konzepte

Bevor du beginnst, solltest du dich mit den folgenden Begriffen vertraut machen:

  • Anmeldedaten für das Threadnetzwerk:Binäres Blob von Thread-TLVs, das den Thread-Netzwerknamen, den Netzwerkschlüssel und andere Properties codiert, die für ein Thread-Gerät erforderlich sind, um einem bestimmten Thread-Netzwerk beizutreten.

  • Bevorzugte Anmeldedaten für das Thread-Netzwerk:Die automatisch ausgewählten Thread-Netzwerk-Anmeldedaten, die über die getPreferredCredentials API für Apps verschiedener Anbieter freigegeben werden können.

  • Border Agent ID (Border Agent-ID): Eine global eindeutige 16-Byte-ID für ein Thread-Border-Router. Diese ID wird von Border-Routeranbietern erstellt und verwaltet.

  • Thread Border Router Setup App:Dies ist Ihre Android-App, mit der neue Thread-Border-Router eingerichtet und den Thread-Netzwerkanmeldedaten in Google Play-Diensten hinzugefügt werden. Ihre App ist der autoritative Inhaber der hinzugefügten Anmeldedaten und hat kostenlosen Zugriff auf die Anmeldedaten.

Viele der Thread Network APIs geben eine Aufgabe zurück, die asynchron abgeschlossen wird. Sie können addOnSuccessListener und addOnFailureListener verwenden, um Callbacks für das Empfangen des Ergebnisses zu registrieren. Weitere Informationen finden Sie in der Dokumentation zu Aufgaben.

Inhaberschaft und Verwaltung von Anmeldedaten

Die Anwendung, die die Anmeldedaten für das Thread-Netzwerk hinzufügt, ist Inhaber der Anmeldedaten und hat volle Zugriffsberechtigungen für die Anmeldedaten. Wenn Sie versuchen, auf Anmeldedaten zuzugreifen, die von anderen Apps hinzugefügt wurden, wird der Fehler PERMISSION_DENIED angezeigt.

Als App-Inhaber wird empfohlen, die in den Google Play-Diensten gespeicherten Anmeldedaten auf dem neuesten Stand zu halten, wenn der Thread-Border-Router aktualisiert wird. Dies bedeutet, dass Anmeldedaten bei Bedarf hinzugefügt, die Anmeldedaten aktualisiert werden, wenn sich der Border-Router ändert und die Anmeldedaten entfernen, wenn der Thread-Border-Router entfernt oder auf die Werkseinstellungen zurückgesetzt wird.

Erkennung von Border-Agents

Anmeldedaten müssen mit einer Border Agent-ID gespeichert werden. Prüfen Sie, ob Ihre App für Thread-Border-Einrichtungen die Border Agent-IDs Ihrer Thread-Border-Router ermitteln kann.

Thread-Border-Router müssen mDNS verwenden, um Thread-Netzwerkinformationen wie Netzwerkname, erweiterte Pantheon-ID und Border-Agent-ID zu bewerben. Die entsprechenden txt-Werte für diese Attribute sind nn, xp bzw. id.

Bei Netzwerken mit Google-Border-Routern erhalten Google Play-Dienste automatisch die Anmeldedaten für das Google Thread-Netzwerk.

SDK in Ihre Android-App einbinden

Führen Sie zuerst die folgenden Schritte aus:

  1. Folgen Sie der Anleitung unter Google Play-Dienste einrichten.

  2. Füge die Datei „Google Play-Dienste“ deiner build.gradle-Datei hinzu:

    implementation 'com.google.android.gms:play-services-threadnetwork:16.0.0-beta01'
    
  3. Optional: Definieren Sie einen BorderAgent data class, um Informationen zu Border-Routern zu speichern. Wir verwenden diese Daten in diesem Leitfaden:

    data class BorderAgentInfo(
      // Network Name max 16 len
      val networkName: String = "",
      val extPanId: ByteArray = ByteArray(16),
      val borderAgentId: ByteArray = ByteArray(16),
      ...
    )
    

Als Nächstes werden wir die empfohlenen Schritte zum Hinzufügen und Verwalten bevorzugter Anmeldedaten durchgehen.

Neue Border-Router-Einrichtungen

Bevor Sie ein neues Netzwerk für neue Border-Router erstellen, sollten Sie zuerst die bevorzugten Netzwerkanmeldedaten verwenden. Dadurch sorgen Sie dafür, dass Thread-Geräte nach Möglichkeit mit einem Thread-Netzwerk verbunden sind.

Durch einen Aufruf von getPreferredCredentials wird eine Aktivität gestartet, in der Nutzer aufgefordert werden, die Netzwerkanfrage zuzulassen. Wenn Anmeldedaten für das Netzwerk im digitalen Thread SDK-Schlüsselbund gespeichert wurden, werden die Anmeldedaten an Ihre App zurückgegeben.

Anmeldedaten anfordern

So fordern Sie die Nutzer zu bevorzugten Anmeldedaten an:

  1. Deklarieren Sie ActivityLauncher:

    private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>
    
  2. Verarbeiten Sie das Ergebnis „Aktivität“, das als ThreadNetworkCredentials zurückgegeben wird:

    preferredCredentialsLauncher =
     registerForActivityResult(
       StartIntentSenderForResult()
     ) { result: ActivityResult ->
       if (result.resultCode == RESULT_OK) {
         val threadNetworkCredentials = ThreadNetworkCredentials.fromIntentSenderResultData(result.data!!)
         Log.d("debug", threadNetworkCredentials.networkName)
       } else {
         Log.d("debug", "User denied request.")
       }
     }
    
  3. Rufe preferredCredentials auf und starte die Aktivität:

    private fun getPreferredThreadNetworkCredentials() {
      ThreadNetwork.getClient(this)
        .preferredCredentials
      .addOnSuccessListener { intentSenderResult ->
        intentSenderResult.intentSender?.let {
          preferredCredentialsLauncher.launch(IntentSenderRequest.Builder(it).build())
          } ?: Log.d("debug", "No preferred credentials found.")
        }
      .addOnFailureListener { e: Exception -> Log.d(TAG, "ERROR: [${e}]") }
    }
    

Neues Thread-Netzwerk erstellen

Wenn in einem Thread-Netzwerk eines Nutzers keine bevorzugten Thread-Netzwerk-Anmeldedaten verfügbar sind, kannst du der addCredentials Play API die Anmeldedaten für die Google Play-Dienste hinzufügen. Dazu musst du ein ThreadBorderAgent-Objekt erstellen und auch ein ThreadNetworkCredentials-Objekt angeben.

Rufe newRandomizeBuilder auf, um ein zufälliges Netzwerk zu erstellen:

val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder().build()

So geben Sie den Thread-Netzwerknamen an:

val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder()
  .setNetworkName("ThreadNetworkSDK")
  .build()

Anmeldedaten hinzufügen

Damit Ihre Thread-Netzwerkanmeldedaten anderen Thread-Anbietern zur Verfügung stehen, müssen wir sie den Google Play-Diensten hinzufügen. Bevor wir unsere neuen Anmeldedaten hinzufügen können, müssen wir auch wissen, zu welchem Border-Router das Thread-Netzwerk gehört.

In diesem Beispiel erstellen wir eine ThreadBorderAgent aus einer Border Agent-ID und übergeben die soeben erstellten neuen Thread-Netzwerk-Anmeldedaten:

private fun addCredentials(borderAgentInfo: BorderAgentInfo, credentialsToBeAdded: ThreadNetworkCredentials) {

  val threadBorderAgent = ThreadBorderAgent.newBuilder(borderAgentInfo.borderAgentId).build()
  Log.d("debug", "border router id:" + threadBorderAgent.id)

  ThreadNetwork.getClient(this)
    .addCredentials(threadBorderAgent, credentialsToBeAdded)
      .addOnSuccessListener {
        Log.d("debug", "Credentials added.")
      }
      .addOnFailureListener { e: Exception -> Log.d(TAG, "ERROR: [${e}]") }
}

Inline-Border-Router erkennen und migrieren

Wenn Sie derzeit Grenzrouter haben, können Sie mit isPreferredCredentials feststellen, ob Ihre Border-Router zum bevorzugten Netzwerk gehören. Diese API fordert den Nutzer nicht zur Berechtigung an und prüft Border-Router-Anmeldedaten mit den Daten, die in den Google Play-Diensten gespeichert sind.

isPreferredCredentails gibt 0 für die Nicht-Übereinstimmung und 1 für die Übereinstimmung als Datentyp Int zurück. Mit IsPreferredCredentialsResult kannst du die Ergebnisse prüfen.

public @interface IsPreferredCredentialsResult {
    int PREFERRED_CREDENTIALS_NOT_FOUND = -1;
    int PREFERRED_CREDENTIALS_NOT_MATCHED = 0;
    int PREFERRED_CREDENTIALS_MATCHED = 1;
}

Zur Verwendung von isPreferredCredentials musst du zuerst ein ThreadNetworkCredentials-Objekt erstellen. Es gibt mehrere Möglichkeiten, ThreadNetworkCredentials zu instanziieren. In den nächsten Schritten werden wir diese Optionen besprechen.

Thread-Netzwerkanmeldedaten nach operativem Dataset

In einigen Fällen ist Ihr Thread-Border-Router bereits mit einem Thread-Netzwerk eingerichtet. Sie möchten dieses Thread-Netzwerk den Google Play-Diensten hinzufügen, um es mit anderen Anbietern zu teilen. Sie können eine ThreadNetworkCredential-Instanz aus einer TLV-Rohdaten zu Active Operational Dataset erstellen:

  1. Konvertieren Sie den Operativen Datensatz in einen ByteArray. Beispiel:

    val activeDataset =
          "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()
    
    fun String.dsToByteArray(): ByteArray {
      return chunked(2).map { it.toInt(16).toByte() }.toByteArray()
    }
    
  2. Verwende fromActiveOperationalDataset, um ThreadNetworkCredentials zu erstellen. Jetzt können Sie den Thread-Netzwerknamen, den Kanal und andere Netzwerkinformationen abrufen. Eine vollständige Liste der Properties findest du unter ThreadNetworkCredentials.

    val threadNetworkCredentials =
        ThreadNetworkCredentials.fromActiveOperationalDataset(activeDataset)
    Log.d(
        "threadNetworkCredentials",
        threadNetworkCredentials.channel.toString() + " - " + threadNetworkCredentials.networkName)
    
  3. Rufe die isPreferredCredentials API auf und übergib die ThreadNetworkCredentials.

    ThreadNetwork.getClient(this)
    .isPreferredCredentials(threadNetworkCredentials)
    .addOnSuccessListener { result ->
      when (result) {
        IsPreferredCredentialsResult.PREFERRED_CREDENTIALS_NOT_MATCHED ->
            Log.d("isPreferredCredentials", "Credentials not matched.")
        IsPreferredCredentialsResult.PREFERRED_CREDENTIALS_MATCHED ->
            Log.d("isPreferredCredentials", "Credentials matched.")
      }
    }
    .addOnFailureListener { e: Exception -> Log.d("isPreferredCredentials", "ERROR: [${e}]") }
    

Thread-Netzwerkanmeldedaten nach Border Agent

Durch eine Border Agent-ID wird ein Border-Router-Gerät eindeutig identifiziert. Um die getCredentialsByBorderAgent API zu verwenden, musst du zuerst ein ThreadBorderAgent-Objekt erstellen und die Border Agent-ID übergeben.

Nachdem du das Objekt ThreadBorderAgent erstellt hast, rufe getCredentialsByBorderAgent auf. Überprüfen Sie, ob die Anmeldedaten gespeichert wurden, um festzustellen, ob sie bevorzugt sind.

private fun isPreferredThreadNetworkByBorderAgent(borderAgentInfo: BorderAgentInfo) {

  val threadBorderAgent = ThreadBorderAgent.newBuilder(borderAgentInfo.borderAgentId).build()
  Log.d("debug", "border router id:" + threadBorderAgent.id)

  var isPreferred = IsPreferredCredentialsResult.PREFERRED_CREDENTIALS_NOT_FOUND
  var borderAgentCredentials: ThreadNetworkCredentials?
  val taskByBorderAgent = ThreadNetwork.getClient(this)
  taskByBorderAgent
      .getCredentialsByBorderAgent(threadBorderAgent)
      .addOnSuccessListener { result: ThreadNetworkCredentialsResult ->
        borderAgentCredentials = result.credentials
        result.credentials?.let {
          taskByBorderAgent.isPreferredCredentials(it).addOnSuccessListener { result ->
            isPreferred = result
          }
        }
      }
      .addOnFailureListener { e: Exception -> Log.d(TAG, "ERROR: [${e}]") }
}

Thread-Netzwerkanmeldedaten nach erweiterter Schwenk-ID

Ähnlich wie bei getPreferredCredentials kannst du auch den Nutzer nach Anmeldedaten von einem Border-Router und der erweiterten Schwenk-ID fragen. getCredentialsByExtendedPanId gibt ein IntentSender zurück und das Ergebnis der Aktivität enthält ein ThreadNetworkCredentials-Objekt, wenn der Nutzer zustimmt.

private fun getCredentialsByExtPanId(borderAgentInfo: BorderAgentInfo) {
  ThreadNetwork.getClient(this)
    .getCredentialsByExtendedPanId(borderAgentInfo.extPanId)
    .addOnSuccessListener { intentSenderResult ->
      intentSenderResult.intentSender?.let {
        preferredCredentialsLauncher.launch(IntentSenderRequest.Builder(it).build())
      }
        ?: Log.d("debug", "No credentials found.")
    }
    .addOnFailureListener { e: Exception -> Log.d(TAG, "ERROR: [${e}]") }
}

Anmeldedaten entfernen

Wenn Ihr Border Router aus Ihrem Zuhause entfernt oder auf die Werkseinstellungen zurückgesetzt wird, müssen Sie dessen Thread-Netzwerk aus den Google Play-Diensten entfernen.

private fun removeCredentials(borderAgentInfo: BorderAgentInfo) {

  val threadBorderAgent = ThreadBorderAgent.newBuilder(borderAgentInfo.borderAgentId).build()
  Log.d("debug", "border router id:" + threadBorderAgent.id)

  ThreadNetwork.getClient(this)
      .removeCredentials(threadBorderAgent)
      .addOnSuccessListener { Log.d("debug", "Credentials removed.") }
      .addOnFailureListener { e: Exception -> Log.d(TAG, "ERROR: [${e}]") }
}

Ressourcen

Weitere Informationen zum Thread Network SDK finden Sie in der API-Referenz.