Thread Network SDK für Android

Das Thread Network SDK bietet Funktionen, die denen eines digitalen Schlüsselanhängers ähneln. So können Ihre Android-Apps Thread-Netzwerk-Anmeldedaten für Google Play-Dienste freigeben. So können deine Apps jedes Thread-Gerät von Smart-Home-Systemen nutzen, ohne Anmeldedaten und Nutzerdaten direkt preiszugeben.

Mit nur wenigen API-Aufrufen können Sie Folgendes tun:

  1. Bevorzugte Thread-Netzwerkanmeldedaten von den Google Play-Diensten anfordern
  2. Neue Border-Router einrichten und Thread-Netzwerkanmeldedaten bei Google hinzufügen Google Play-Dienste.
  3. Wenn ihr bereits einen Border-Router vor Ort habt, könnt ihr prüfen, Router im bevorzugten Netzwerk und migrieren diese bei Bedarf.

Es gibt mehrere User Journeys und Entwickler-Journeys zu berücksichtigen. Wir werden die meisten in diesem Leitfaden zusammen mit anderen wichtigen Funktionen und der empfohlenen Verwendung.

Wichtige Terminologie und API-Konzepte

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

  • Thread-Netzwerk-Anmeldedaten: Binärer Blob von Thread-TLVs, der den Thread-Netzwerknamen, den Netzwerkschlüssel und andere Eigenschaften codiert, die ein Thread-Gerät zum Beitritt zu einem bestimmten Thread-Netzwerk benötigt.

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

  • Border-Agent-ID: Eine 16-Byte-global eindeutige ID für ein Thread-Border-Router-Gerät. Diese ID wird von Anbietern von Border-Routern erstellt und verwaltet.

  • Einrichtungs-App für Thread-Border-Router:Dies ist Ihre Android-App, die neuen Thread-Border-Router-Geräten und fügt die Thread-Netzwerkanmeldedaten Google Play-Dienste. Ihre App ist der maßgebliche Inhaber der hinzugefügten Anmeldedaten erstellt und auf sie zugreifen kann.

Viele Thread-Netzwerk-APIs geben eine Fehlermeldung Aufgabe das asynchron abgeschlossen wird. Mit addOnSuccessListener und addOnFailureListener können Sie Callbacks zum Empfangen des Ergebnisses registrieren. Weitere Informationen finden Sie im Aufgabe Dokumentation.

Inhaberschaft und Verwaltung von Anmeldedaten

Die App, die die Thread-Netzwerkanmeldedaten hinzufügt, wird zum Inhaber der Anmeldedaten und hat uneingeschränkte Zugriffsberechtigungen. Wenn Sie versuchen, für den Zugriff auf Anmeldedaten, die von anderen Apps hinzugefügt wurden, erhältst du ein PERMISSION_DENIED Fehler.

Als App-Inhaber sollten Sie die Anmeldedaten in Google Die Dienste werden auf dem neuesten Stand gehalten, wenn das Netzwerk des Thread-Border-Routers aktualisiert wird. Dieses das Hinzufügen von Anmeldedaten bei Bedarf, das Aktualisieren der Anmeldedaten, wenn der Rand ändern sich die Thread-Netzwerkanmeldedaten des Routers. Der Thread-Border-Router wurde entfernt oder auf die Werkseinstellungen zurückgesetzt.

Erkennung des Border Agent

Anmeldedaten müssen mit einer Border Agent-ID gespeichert werden. Sie müssen dafür sorgen, dass die Thread Border Router Setup App die Border-Agent-IDs Ihrer Thread-Border-Router ermitteln kann.

Thread-Border-Router müssen mDNS verwenden, um Thread-Netzwerkinformationen zu veröffentlichen, einschließlich des Netzwerknamens, der erweiterten PAN-ID und der Border-Agent-ID. Die entsprechenden txt-Werte für diese Attribute sind nn, xp und id.

Bei Netzwerken mit Google-Border-Routern werden die Google Play-Dienste ruft Google Thread-Netzwerkanmeldedaten ab.

SDK in Ihre Android-App einbinden

Führen Sie zunächst die folgenden Schritte aus:

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

  2. Fügen Sie der Datei build.gradle die Abhängigkeit von Google Play-Diensten hinzu:

    implementation 'com.google.android.gms:play-services-threadnetwork:16.2.1'
    
  3. Optional: Definieren Sie eine BorderAgent-Datenklasse zum Speichern des Border-Routers. Informationen. Diese Daten werden in diesem Leitfaden verwendet:

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

Als Nächstes sehen wir uns die empfohlenen Schritte zum Hinzufügen und Verwalten von bevorzugten Anmeldedaten.

Neue Border-Router-Einrichtungen

Bevor Sie ein neues Netzwerk für neue Border-Router erstellen, ist es wichtig, dass Sie versuchen, Ihre bevorzugten Anmeldedaten für das Netzwerk zu verwenden. Dadurch wird sichergestellt, Thread-Geräte werden nach Möglichkeit mit einem einzelnen Thread-Netzwerk verbunden.

Ein Aufruf von getPreferredCredentials startet eine Aktivität, bei der Nutzer aufgefordert werden, die Netzwerkanfrage zuzulassen. Wenn Netzwerkanmeldedaten im digitalen Schlüsselbund des Thread SDK gespeichert wurden, werden sie an Ihre App zurückgegeben.

Anmeldedaten anfordern

So fordern Sie den Nutzer zur Eingabe bevorzugter Anmeldedaten auf:

  1. Deklarieren Sie ein ActivityLauncher:

    private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>
    
  2. Verarbeiten Sie 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. Wenn Sie einen neuen Thread-Border-Router einrichten, sollten Sie preferredCredentials und starten Sie die Aktivität. Dadurch wird sichergestellt, dass Ihr neuer Thread Border Router dieselben Anmeldedaten verwendet, die bereits als bevorzugt auf dem Smartphone gespeichert sind. So wird die Konvergenz verschiedener TBRs in dasselbe Netzwerk gefördert.

    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}]") }
    }
    
  4. Wenn sich Ihr Anwendungsfall auf die Einrichtung von Geräten ohne TBR bezieht, z. B. ein neues Gerät Matter-over-Thread-Endgerät wird empfohlen, das allActiveCredentials zu verwenden. api zum Abrufen von Anmeldedaten. Bei diesem Aufruf wird nach TBRs im lokalen Netzwerk gesucht. Es werden also keine Anmeldedaten zurückgegeben, die lokal nicht über einen vorhandenen TBR verfügbar sind.

    // Creates the IntentSender result launcher for the getAllActiveCredentials API
    private val getAllActiveCredentialsLauncher =
      registerForActivityResult(
        StartIntentSenderForResult()
      ) { result: ActivityResult ->
        if (result.resultCode == RESULT_OK) {
          val activeCredentials: List<ThreadNetworkCredentials> =
            ThreadNetworkCredentials.parseListFromIntentSenderResultData(
              result.data!!
            )
          // Use the activeCredentials list
        } else {
          // The user denied to share!
        }
      }
    
    // Invokes the getAllActiveCredentials API and starts the dialog activity with the returned
    // IntentSender
    threadNetworkClient
    .getAllActiveCredentials()
    .addOnSuccessListener { intentSenderResult: IntentSenderResult ->
      val intentSender = intentSenderResult.intentSender
      if (intentSender != null) {
        getAllActiveCredentialsLauncher.launch(
          IntentSenderRequest.Builder(intentSender).build()
        )
      } else {
        // No active network credentials found!
      }
    }
    // Handles the failure
    .addOnFailureListener { e: Exception ->
      // Handle the exception
    }
    

Neues Thread-Netzwerk erstellen

Wenn im Thread-Netzwerk eines Nutzers weder bevorzugte Thread-Netzwerk-Anmeldedaten noch aktive Thread-Anmeldedaten verfügbar sind, können Sie mit der addCredentials API Anmeldedaten zu Google Play-Diensten hinzufügen. Dazu musst du ein ThreadBorderAgent erstellen und ein ThreadNetworkCredentials-Objekt angeben.

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

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

So legen Sie den Namen des Thread-Netzwerks fest:

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

Anmeldedaten hinzufügen

Damit Ihre Thread-Netzwerk-Anmeldedaten für andere Thread-Anbieter verfügbar sind, 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-Gerät dieses Thread-Netzwerk gehört.

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

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 vor Ort erkennen und migrieren

Wenn Sie derzeit Border-Router im Einsatz haben, können Sie mit isPreferredCredentials feststellen, ob Ihre Border-Router zum bevorzugten Netzwerk gehören. Bei dieser API wird der Nutzer nicht um Erlaubnis gebeten. Die Anmeldedaten des Border-Routers werden mit den in den Google Play-Diensten gespeicherten Daten abgeglichen.

isPreferredCredentails gibt 0 für keine Übereinstimmung und 1 für als Datentyp Int. Du kannst IsPreferredCredentialsResult verwenden um die Ergebnisse zu überprüfen.

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

Wenn Sie isPreferredCredentials verwenden möchten, müssen Sie zuerst ein ThreadNetworkCredentials-Objekt erstellen. Es gibt mehrere Möglichkeiten, ThreadNetworkCredentials zu instanziieren. In den nächsten Schritten werden diese Optionen erläutert.

Thread-Netzwerkanmeldedaten nach Betriebsdatensatz

Es kann vorkommen, dass Ihr Thread-Border-Router bereits mit einem Thread-Netzwerk und du möchtest dieses Thread-Netzwerk den Google Play-Diensten hinzufügen um sie mit anderen Anbietern zu teilen. Sie können eine ThreadNetworkCredential-Instanz aus einer Rohliste von TLVs für Thread Active Operational Datasets erstellen:

  1. Konvertieren Sie das operative Dataset in ein ByteArray-Objekt. Beispiel:

    val activeDataset =
          "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()
    
    fun String.dsToByteArray(): ByteArray {
      return chunked(2).map { it.toInt(16).toByte() }.toByteArray()
    }
    
  2. Erstellen Sie die ThreadNetworkCredentials mit fromActiveOperationalDataset. Wenn der Vorgang erfolgreich war, kannst du den Namen, den Kanal und andere Informationen zum Threadnetzwerk abrufen. Eine vollständige Liste der Unterkünfte finden Sie unter ThreadNetworkCredentials.

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

Mit einer Border Agent-ID wird ein Border-Router-Gerät eindeutig identifiziert. Um getCredentialsByBorderAgent API verwenden möchten, müssen Sie zuerst eine ThreadBorderAgent-Objekt und übergeben Sie die Border Agent-ID.

Nachdem Sie das ThreadBorderAgent-Objekt erstellt haben, rufen Sie getCredentialsByBorderAgent. Wenn die Anmeldedaten gespeichert wurden, prüfen Sie, ob sie als bevorzugte Anmeldedaten festgelegt 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 Extended Pan-ID

Ähnlich wie bei getPreferredCredentials können Sie den Nutzer auch zu einer Eingabe auffordern Anmeldedaten der erweiterten Panorama-ID eines Border-Routers. getCredentialsByExtendedPanId gibt einen IntentSender zurück und das Aktivitätsergebnis 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 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