Thread Network SDK für Android

Das Thread Network SDK bietet Funktionen, die einem digitalen Schlüsselanhänger ähneln, sodass Ihre Android-Apps Thread-Netzwerkanmeldedaten mit Google Play-Diensten teilen können. Dadurch können deine 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 das Thread-Netzwerk von Google Play-Diensten anfordern
  2. Richten Sie neue Border-Router ein und fügen Sie den Google Play-Diensten Ihre Anmeldedaten für das Thread-Netzwerk hinzu.
  3. Wenn Sie bereits Border-Router im Feld haben, können Sie prüfen, ob sich die Border-Router im bevorzugten Netzwerk befinden, und diese bei Bedarf migrieren.

Es gibt verschiedene Wege für Nutzer und Entwickler. Die meisten davon werden in diesem Leitfaden behandelt. Außerdem werden weitere wichtige Funktionen und eine empfohlene Nutzung behandelt.

Wichtige Begriffe und API-Konzepte

Bevor Sie beginnen, sollten Sie sich mit den folgenden Begriffen vertraut machen:

  • Anmeldedaten des Thread-Netzwerks:Binäres Blob von Thread-TLVs, das den Thread-Netzwerknamen, den Netzwerkschlüssel und andere Attribute codiert, die von einem Thread-Gerät für die Verbindung mit einem bestimmten Thread-Netzwerk benötigt werden.

  • Bevorzugte Thread-Netzwerkanmeldedaten:Die automatisch ausgewählten Thread-Netzwerkanmeldedaten, die über die getPreferredCredentials API mit Apps verschiedener Anbieter geteilt werden können.

  • Border Agent-ID:Eine global eindeutige 16-Byte-ID für einen Thread-Border-Router. Diese ID wird von Anbietern des Border-Routers erstellt und verwaltet.

  • Die App für die Einrichtung des Thread-Border-Routers:Dies ist Ihre Android-App, mit der neue Thread-Border-Router eingerichtet und die Thread-Netzwerkanmeldedaten den Google Play-Diensten hinzugefügt werden. Ihre App ist der rechtmäßige Inhaber der hinzugefügten Anmeldedaten und hat Zugriff darauf.

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

Anmeldedaten – Inhaberschaft und Verwaltung

Die App, mit der die Thread-Netzwerkanmeldedaten hinzugefügt werden, wird zum Inhaber der Anmeldedaten und kann uneingeschränkt darauf zugreifen. Wenn Sie versuchen, auf Anmeldedaten zuzugreifen, die von anderen Apps hinzugefügt wurden, wird der Fehler PERMISSION_DENIED angezeigt.

Als App-Inhaber sollten die in den Google Play-Diensten gespeicherten Anmeldedaten immer aktualisiert werden, wenn das Thread-Border-Netzwerk aktualisiert wird. Dies bedeutet, dass bei Bedarf Anmeldedaten hinzugefügt, Anmeldedaten aktualisiert werden, wenn sich die Anmeldedaten des Thread-Netzwerks des Border-Routers ändern, und die Anmeldedaten entfernt werden, wenn der Thread-Border-Router entfernt oder auf die Werkseinstellungen zurückgesetzt wird.

Border Agent-Erkennung

Anmeldedaten müssen mit einer Border Agent-ID gespeichert werden. Prüfen Sie zuerst, ob die App zur Einrichtung des Thread-Border-Routers die Border Agent-IDs der Thread-Border-Router ermitteln können.

Thread-Border-Router müssen mDNS verwenden, um Thread-Netzwerkinformationen wie den Netzwerknamen, die erweiterte Pan-ID und die 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 Anmeldedaten für das Google Thread-Netzwerk.

SDK in Ihre Android-App einbinden

So gehts:

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

  2. Fügen Sie der Datei build.gradle die Abhängigkeit für Google Play-Dienste hinzu:

    implementation 'com.google.android.gms:play-services-threadnetwork:16.0.0'
    
  3. Optional: Definieren Sie eine BorderAgent-Datenklasse, um Informationen für den Border-Router 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 lernen Sie, wie Sie bevorzugte Anmeldedaten hinzufügen und verwalten.

Neue Border-Routereinrichtung

Bevor Sie ein neues Netzwerk für neue Border-Router erstellen, sollten Sie zuerst die bevorzugten Netzwerk-Anmeldedaten ausprobieren. Dadurch werden Thread-Geräte nach Möglichkeit mit einem einzigen Thread-Netzwerk verbunden.

Durch einen Aufruf von getPreferredCredentials wird eine Aktivität gestartet, die Nutzer dazu auffordert, die Netzwerkanfrage zuzulassen. Wenn Netzwerkanmeldedaten im digitalen Thread SDK-Schlüsselbund gespeichert wurden, werden die Anmeldedaten an Ihre App zurückgegeben.

Anmeldedaten anfordern

So fragen Sie den Nutzer nach bevorzugten Anmeldedaten:

  1. ActivityLauncher deklarieren:

    private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>
    
  2. Verarbeite das Aktivitätsergebnis, 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. Rufen Sie preferredCredentials auf und starten Sie 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 im Thread-Netzwerk eines Nutzers keine bevorzugten Thread-Netzwerkanmeldedaten verfügbar sind, können Sie die addCredentials API verwenden, um Anmeldedaten für die Google Play-Dienste hinzuzufügen. Dazu müssen Sie ein ThreadBorderAgent erstellen und außerdem ein ThreadNetworkCredentials-Objekt angeben.

Rufen Sie zum Erstellen eines zufälligen Netzwerks den newRandomizeBuilder auf:

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 wissen, zu welchem Border-Router das Thread-Netzwerk gehört.

In diesem Beispiel erstellen wir ein ThreadBorderAgent aus einer Border Agent-ID und übergeben die neu erstellten Thread-Netzwerkanmeldedaten:

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}]") }
}

Border-Router im Feld erkennen und migrieren

Wenn Sie derzeit Grenzrouter innerhalb des Felds nutzen, können Sie mithilfe von isPreferredCredentials feststellen, ob Ihre Grenzrouter zum bevorzugten Netzwerk gehören. Diese API fordert den Nutzer nicht zur Berechtigung auf und prüft die Anmeldedaten des Border-Routers mit den in Google Play-Diensten gespeicherten Daten.

isPreferredCredentails gibt 0 für den nicht übereinstimmenden Wert und 1 für den Abgleich als Int-Datentyp zurück. Mit IsPreferredCredentialsResult können Sie 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 müssen Sie zuerst ein ThreadNetworkCredentials-Objekt erstellen. Es gibt mehrere Möglichkeiten, ThreadNetworkCredentials zu instanziieren. In den nächsten Schritten werden diese Optionen beschrieben.

Anmeldedaten für das Thread-Netzwerk nach operativem Dataset

Es gibt Fälle, in denen dein Thread-Border-Router bereits mit einem Thread-Netzwerk eingerichtet ist und du dieses Thread-Netzwerk den Google Play-Diensten hinzufügen möchtest, um es mit anderen Anbietern zu teilen. Sie können eine ThreadNetworkCredential-Instanz aus einer unbearbeiteten TLV-Liste für das aktive Thread-Dataset erstellen:

  1. Das operative Dataset in ein ByteArray konvertieren. Beispiel:

    val activeDataset =
          "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()
    
    fun String.dsToByteArray(): ByteArray {
      return chunked(2).map { it.toInt(16).toByte() }.toByteArray()
    }
    
  2. Verwenden Sie fromActiveOperationalDataset, um die ThreadNetworkCredentials zu erstellen. Wenn der Vorgang erfolgreich war, können Sie den Thread-Netzwerknamen, den Kanal und andere Netzwerkinformationen abrufen. Eine vollständige Liste der Attribute finden Sie unter ThreadNetworkCredentials.

    val threadNetworkCredentials =
        ThreadNetworkCredentials.fromActiveOperationalDataset(activeDataset)
    Log.d(
        "threadNetworkCredentials",
        threadNetworkCredentials.channel.toString() + " - " + threadNetworkCredentials.networkName)
    
  3. Rufen Sie die isPreferredCredentials API auf und übergeben Sie 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}]") }
    

Anmeldedaten für das Thread-Netzwerk nach Border Agent

Eine Border Agent-ID dient zur eindeutigen Identifizierung eines Border-Routers. Wenn Sie die getCredentialsByBorderAgent API verwenden möchten, müssen Sie zuerst ein ThreadBorderAgent-Objekt erstellen und die Border Agent-ID übergeben.

Nachdem Sie das ThreadBorderAgent-Objekt erstellt haben, rufen Sie getCredentialsByBorderAgent auf. Wenn die Anmeldedaten gespeichert wurden, prüfe, ob sie bevorzugt werden.

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}]") }
}

Anmeldedaten für das Thread-Netzwerk nach Extended Pan ID

Ähnlich wie bei getPreferredCredentials können Sie den Nutzer auch über die PAN des Border-Routers nach Anmeldedaten fragen. getCredentialsByExtendedPanId gibt ein IntentSender zurück und das Activity-Ergebnis enthält ein ThreadNetworkCredentials-Objekt, wenn der Nutzer die Anfrage genehmigt.

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 sein 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.