Das Thread Network SDK bietet Funktionen, die einem digitalen Schlüsselbund ähneln. Damit können Ihre Android-Apps Thread-Netzwerkanmeldedaten für die Google Play-Dienste freigeben. So können deine Apps jedes Thread-Gerät aus jedem Smart-Home-Ökosystem einrichten, ohne dass Anmeldedaten und Nutzerdaten direkt offengelegt werden.
Mit nur wenigen API-Aufrufen können Sie:
- Anmeldedaten für das bevorzugte Thread-Netzwerk von den Google Play-Diensten anfordern.
- Richte neue Thread Border Router (TBR)s ein und füge deine Thread-Netzwerkanmeldedaten zu den Google Play-Diensten hinzu.
- Wenn Sie bereits TBRs im Feld haben, können Sie prüfen, ob sich Ihre TBRs im bevorzugten Netzwerk befinden, und sie bei Bedarf migrieren.
Es gibt mehrere Nutzer- und Entwicklerpfade, die berücksichtigt werden müssen. Die meisten davon werden in diesem Leitfaden behandelt, zusammen mit anderen wichtigen Funktionen und der empfohlenen Verwendung.
Wichtige Begriffe und API-Konzepte
Bevor Sie beginnen, sollten Sie die folgenden Begriffe kennen:
Anmeldedaten für das Thread-Netzwerk:Binärer Blob von Thread-TLVs, der den Namen des Thread-Netzwerks, den Netzwerkschlüssel und andere Attribute codiert, die ein Thread-Gerät benötigt, um einem bestimmten Thread-Netzwerk beizutreten.
Bevorzugte Thread-Netzwerkanmeldedaten:Die automatisch ausgewählten Thread-Netzwerkanmeldedaten, die über die
getPreferredCredentialsAPI mit Apps anderer Anbieter geteilt werden können.Border-Agent-ID: Eine global eindeutige 16-Byte-ID für ein TBR-Gerät. Diese ID wird von border router-Anbietern erstellt und verwaltet.
TBR-Einrichtungs-App:Dies ist deine Android-App, mit der neue TBR-Geräte eingerichtet und die Anmeldedaten für das Thread-Netzwerk den Google Play-Diensten hinzugefügt werden. Ihre App ist der maßgebliche Inhaber der hinzugefügten Anmeldedaten und hat Zugriff darauf.
Viele der Thread Network APIs geben eine Task zurück, die asynchron abgeschlossen wird. Mit addOnSuccessListener und addOnFailureListener können Sie Callbacks registrieren, um das Ergebnis zu erhalten. Weitere Informationen finden Sie in der Dokumentation zu Aufgaben.
Eigentümerschaft und Verwaltung von Anmeldedaten
Die App, die die Thread-Netzwerkanmeldedaten hinzufügt, wird zum Inhaber der Anmeldedaten und hat uneingeschränkte Berechtigungen für den Zugriff auf die Anmeldedaten. Wenn Sie versuchen, auf Anmeldedaten zuzugreifen, die von anderen Apps hinzugefügt wurden, erhalten Sie den Fehler PERMISSION_DENIED.
Als App-Inhaber sollten Sie die in den Google Play-Diensten gespeicherten Anmeldedaten auf dem neuesten Stand halten, wenn das TBR-Netzwerk aktualisiert wird. Das bedeutet, dass Anmeldedaten bei Bedarf hinzugefügt, bei einer Änderung der Thread-Netzwerk-Anmeldedaten des border router aktualisiert und bei einer Entfernung oder einem Zurücksetzen auf die Werkseinstellungen des TBR entfernt werden müssen.
Border Agent-Erkennung
Anmeldedaten müssen mit einer Border Agent-ID gespeichert werden. Du musst dafür sorgen, dass deine TBR-Einrichtungs-App die Border-Agent-IDs deiner TBR-Geräte ermitteln kann.
TBRs müssen mDNS verwenden, um Thread-Netzwerkinformationen zu bewerben, 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 Thread Border Router (gTBR)s rufen die Google Play-Dienste automatisch die Anmeldedaten für das Google Thread-Netzwerk ab.
SDK in Ihre Android-App einbinden
Führen Sie folgende Schritte aus:
Folgen Sie der Anleitung unter Google Play-Dienste einrichten.
Fügen Sie der Datei
build.gradledie Abhängigkeit für Google Play-Dienste hinzu:implementation 'com.google.android.gms:play-services-threadnetwork:16.2.1'Optional: Definieren Sie eine
BorderAgent-Datenklasse, um TBR-Informationen 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 gehen wir die empfohlenen Schritte zum Hinzufügen und Verwalten bevorzugter Anmeldedaten durch.
Neue Thread-Border-Router-Einrichtungen
Bevor du ein neues Netzwerk für neue Border-Router erstellst, solltest du zuerst die Anmeldedaten des bevorzugten Netzwerks verwenden. So wird sichergestellt, dass Thread-Geräte nach Möglichkeit mit einem einzigen Thread-Netzwerk verbunden sind.
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 die Anmeldedaten an Ihre App zurückgegeben.
Anmeldedaten anfordern
So fordern Sie den Nutzer auf, bevorzugte Anmeldedaten anzugeben:
Deklarieren Sie ein
ActivityLauncher:private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>Verarbeite das Aktivitätsergebnis, das als
ThreadNetworkCredentialszurü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.") } }Wenn du eine neue TBR einrichtest, solltest du
preferredCredentialsaufrufen und die Aktivität starten. Durch diesen Aufruf wird sichergestellt, dass dein neues TBR dieselben Anmeldedaten verwendet, die bereits als bevorzugt auf dem Smartphone gespeichert sind. Dadurch wird die Konvergenz verschiedener TBRs im selben 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}]") } }Wenn sich dein Anwendungsfall auf die Einrichtung von Nicht-TBR-Geräten bezieht, z. B. ein neues Matter-over-Thread-Endgerät, solltest du die
allActiveCredentialsAPI verwenden, um Anmeldedaten abzurufen. Bei diesem Aufruf wird nach TBRs im lokalen Netzwerk gesucht. Es werden also keine Anmeldedaten zurückgegeben, die nicht lokal ü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 noch aktive Thread-Netzwerkanmeldedaten verfügbar sind, kannst du die addCredentials API verwenden, um den Google Play-Diensten Anmeldedaten hinzuzufügen. Dazu müssen Sie ein ThreadBorderAgent erstellen und ein ThreadNetworkCredentials-Objekt angeben.
Rufen Sie die newRandomizeBuilder auf, um ein zufälliges Netzwerk zu erstellen:
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder().build()
So gibst du den Namen des Thread-Netzwerks an:
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder()
.setNetworkName("ThreadNetworkSDK")
.build()
Anmeldedaten hinzufügen
Damit deine Anmeldedaten für das Thread-Netzwerk für andere Thread-Anbieter verfügbar sind, müssen wir sie den Google Play-Diensten hinzufügen. Bevor wir die neuen Anmeldedaten hinzufügen können, müssen wir auch wissen, zu welchem TBR-Gerät dieses Thread-Netzwerk gehört.
In diesem Beispiel erstellen wir ein ThreadBorderAgent aus einer Border-Agent-ID und übergeben die neuen Thread-Netzwerkanmeldedaten, die Sie gerade erstellt haben:
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 routers im Feld erkennen und migrieren
Wenn Sie border routers im Feld haben, können Sie mit isPreferredCredentials feststellen, ob Ihre border routers zum bevorzugten Netzwerk gehören. Diese API fordert den Nutzer nicht zur Erteilung einer Berechtigung auf und gleicht die border router-Anmeldedaten mit den in den Google Play-Diensten gespeicherten Daten ab.
isPreferredCredentials gibt 0 für nicht übereinstimmende und 1 für übereinstimmende Werte als Int-Datentyp zurück. Sie können IsPreferredCredentialsResult verwenden, um Ihre Ergebnisse zu prü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 gehen wir diese Optionen durch.
Thread-Netzwerkanmeldedaten nach Operational Dataset
Es kann vorkommen, dass dein TBR 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. Du kannst eine ThreadNetworkCredential-Instanz aus einer Thread Active Operational Dataset-TLV-Rohliste erstellen:
Konvertieren Sie das operative Dataset in ein
ByteArray. Beispiel:val activeDataset = "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()fun String.dsToByteArray(): ByteArray { return chunked(2).map { it.toInt(16).toByte() }.toByteArray() }Verwenden Sie
fromActiveOperationalDataset, um dieThreadNetworkCredentialszu erstellen. Wenn der Vorgang erfolgreich abgeschlossen wurde, kannst du den Namen, den Kanal und andere Netzwerkinformationen des Thread-Netzwerks abrufen. Eine vollständige Liste der Attribute findest du unter ThreadNetworkCredentials.val threadNetworkCredentials = ThreadNetworkCredentials.fromActiveOperationalDataset(activeDataset) Log.d( "threadNetworkCredentials", threadNetworkCredentials.channel.toString() + " - " + threadNetworkCredentials.networkName)Rufen Sie die
isPreferredCredentialsAPI auf und übergeben Sie dieThreadNetworkCredentials.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
Eine Border-Agent-ID identifiziert ein TBR-Gerät eindeutig. 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üfen Sie, 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}]") }
}
Thread-Netzwerkanmeldedaten nach erweiterter PAN-ID
Ähnlich wie bei getPreferredCredentials kannst du den Nutzer auch nach Anmeldedaten aus der erweiterten PAN-ID eines TBR fragen. getCredentialsByExtendedPanId gibt ein 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 dein border router-Gerät aus deinem Zuhause entfernt oder auf die Werkseinstellungen zurückgesetzt wird, musst du das 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 findest du in der API-Referenz.