Pakiet SDK sieci Thread zapewnia funkcje podobne do cyfrowego breloczka, dzięki czemu aplikacje na Androida mogą udostępniać dane logowania do sieci Thread usługom Google Play. Dzięki temu aplikacje mogą konfigurować dowolne urządzenie Thread z dowolnego ekosystemu inteligentnego domu bez bezpośredniego udostępniania danych logowania i danych użytkownika.
Wystarczy kilka wywołań interfejsu API, aby:
- poprosić usługi Google Play o preferowane dane logowania do sieci Thread;
- skonfigurować nowe Thread Border Router (TBR) i dodać dane logowania do sieci Thread do usług Google Play;
- jeśli masz już routery TBRTBR w terenie, możesz sprawdzić, czy należą one do preferowanej sieci, i w razie potrzeby je przenieść.
Trzeba tu uwzględnić różne ścieżki użytkowników i deweloperów. Większość z nich omówimy w tym przewodniku wraz z innymi najważniejszymi funkcjami i zalecanym sposobem użycia.
Kluczowe terminy i koncepcje interfejsu API
Zanim zaczniesz, warto zapoznać się z tymi terminami:
Dane logowania do sieci Thread: binarny obiekt blob zawierający TLV Thread, który koduje nazwę sieci Thread, klucz sieci i inne właściwości wymagane przez urządzenie Thread do dołączenia do danej sieci Thread.
Preferowane dane logowania do sieci Thread: automatycznie wybrane dane logowania do sieci Thread, które można udostępniać aplikacjom różnych dostawców za pomocą interfejsu API
getPreferredCredentials.Identyfikator agenta granicznego: 16-bajtowy, globalnie unikalny identyfikator urządzenia TBR. Ten identyfikator jest tworzony i zarządzany przez border router dostawców.
TBR aplikacja do konfiguracji: jest to aplikacja na Androida, która konfiguruje nowe TBR urządzenia i dodaje dane logowania do sieci Thread do usług Google Play. Twoja aplikacja jest autorytatywnym właścicielem dodanych danych logowania i ma do nich dostęp.
Wiele interfejsów API sieci Thread zwraca zadanie , które jest wykonywane asynchronicznie. Aby zarejestrować wywołania zwrotne do odbierania wyników, możesz użyć metod addOnSuccessListener i addOnFailureListener. Więcej informacji znajdziesz w dokumentacji zadania.
Własność danych logowania i ich utrzymanie
Aplikacja, która dodaje dane logowania do sieci Thread, staje się ich właścicielem i ma pełne uprawnienia dostępu do nich. Jeśli spróbujesz uzyskać dostęp do danych logowania dodanych przez inne aplikacje, otrzymasz błąd PERMISSION_DENIED.
Jako właściciel aplikacji zalecamy, aby w przypadku aktualizacji sieci TBR aktualizować dane logowania przechowywane w usługach Google Play. Oznacza to dodawanie danych logowania w razie potrzeby, aktualizowanie ich w przypadku zmiany danych logowania do sieci Thread routera border router's oraz usuwanie danych logowania, gdy TBR zostanie usunięty lub przywrócony do ustawień fabrycznych.
Wykrywanie agenta granicznego
Dane logowania muszą być zapisane z identyfikatorem agenta granicznego. Musisz się upewnić, że aplikacja do konfiguracji TBR może określić identyfikatory agentów granicznych Twoich TBRów.
TBRs muszą używać mDNS do reklamowania informacji o sieci Thread,
w tym nazwy sieci, rozszerzonego identyfikatora PAN i identyfikatora agenta granicznego. Odpowiednie wartości txt tych atrybutów to odpowiednio nn, xp i id.
W przypadku sieci z Google Thread Border Router (gTBR) usługi Google Play automatycznie pobierają dane logowania do sieci Google Thread.
Integracja pakietu SDK z aplikacją na Androida
Aby rozpocząć, wykonaj te czynności:
Postępuj zgodnie z instrukcjami podanymi w artykule Konfigurowanie usług Google Play.
Dodaj zależność od usług Google Play do pliku
build.gradle:implementation 'com.google.android.gms:play-services-threadnetwork:16.2.1'Opcjonalnie: zdefiniuj klasę danych
BorderAgentdo przechowywania TBR informacji. Będziemy używać tych danych w tym przewodniku:data class BorderAgentInfo( // Network Name max 16 len val networkName: String = "", val extPanId: ByteArray = ByteArray(16), val borderAgentId: ByteArray = ByteArray(16), ... )
Następnie omówimy zalecane kroki dodawania preferowanych danych logowania i zarządzania nimi.
Konfiguracja nowych routerów granicznych Thread
Zanim utworzysz nową sieć dla nowych routerów granicznych, spróbuj najpierw użyć preferowanych danych logowania do sieci. Dzięki temu urządzenia Thread będą w miarę możliwości połączone z jedną siecią Thread.
Wywołanie getPreferredCredentials uruchamia aktywność, która prosi użytkowników o zezwolenie na żądanie sieciowe. Jeśli dane logowania do sieci zostały zapisane w cyfrowym breloczku pakietu SDK Thread, zostaną zwrócone do Twojej aplikacji.
Żądanie danych logowania
Aby poprosić użytkownika o preferowane dane logowania:
Zadeklaruj
ActivityLauncher:private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>Obsłuż wynik aktywności zwrócony jako
ThreadNetworkCredentials: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.") } }Jeśli konfigurujesz nowy TBR, zalecamy wywołanie
preferredCredentialsi uruchomienie aktywności. To wywołanie zapewni że nowy TBR będzie używać tych samych danych logowania, które są już zapisane jako preferowane w telefonie, co ułatwi konwergencję różnych routerów TBR do tej samej sieci.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}]") } }Jeśli Twój przypadek użycia dotyczy konfigurowania urządzeń innych niż TBR, np. nowego urządzenia końcowego Matter-over-Thread, zalecamy użycie interfejsu API
allActiveCredentialsdo pobierania danych logowania. To wywołanie spowoduje wyszukanie routerów TBR w sieci lokalnej, a więc nie zwróci danych logowania, które nie są dostępne lokalnie przez istniejący router TBR.// 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 }
Tworzenie nowej sieci Thread
Jeśli w sieci Thread użytkownika nie ma preferowanych danych logowania do sieci Thread ani aktywnych danych logowania do sieci Thread, możesz użyć interfejsu API addCredentials, aby dodać dane logowania do usług Google Play. Aby to zrobić, musisz utworzyć ThreadBorderAgent i podać obiekt ThreadNetworkCredentials.
Aby utworzyć losową sieć, wywołaj newRandomizeBuilder:
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder().build()
Aby określić nazwę sieci Thread:
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder()
.setNetworkName("ThreadNetworkSDK")
.build()
Dodawanie danych logowania
Aby udostępnić dane logowania do sieci Thread innym dostawcom Thread, musimy dodać je do usług Google Play. Zanim dodamy nowe dane logowania, musimy też wiedzieć, do którego TBR urządzenia należy ta sieć Thread.
W tym przykładzie utworzymy ThreadBorderAgent na podstawie identyfikatora agenta granicznego i przekażemy nowe dane logowania do sieci Thread, które właśnie zostały utworzone:
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}]") }
}
Wykrywanie i migracja border router w terenie
Jeśli masz border router w terenie, możesz użyć
isPreferredCredentials, aby sprawdzić, czy Twoje border router należą
do preferowanej sieci. Ten interfejs API nie prosi użytkownika o uprawnienia i sprawdza border router dane logowania routera granicznego z danymi przechowywanymi w usługach Google Play.
W przypadku braku dopasowania isPreferredCredentials zwraca 0, a w przypadku dopasowania 1 jako typ danych Int. Aby sprawdzić wyniki, możesz użyć IsPreferredCredentialsResult.
public @interface IsPreferredCredentialsResult {
int PREFERRED_CREDENTIALS_NOT_FOUND = -1;
int PREFERRED_CREDENTIALS_NOT_MATCHED = 0;
int PREFERRED_CREDENTIALS_MATCHED = 1;
}
Aby użyć isPreferredCredentials, musisz najpierw utworzyć obiekt ThreadNetworkCredentials. Istnieje kilka sposobów utworzenia instancji ThreadNetworkCredentials. W kolejnych krokach omówimy te opcje.
Dane logowania do sieci Thread według operacyjnego zbioru danych
W niektórych przypadkach router TBR jest już skonfigurowany z siecią Thread
i chcesz dodać tę sieć Thread do usług Google Play
aby udostępnić ją innym dostawcom. Możesz utworzyć instancję ThreadNetworkCredential na podstawie listy TLV surowego aktywnego operacyjnego zbioru danych Thread:
Przekonwertuj operacyjny zbiór danych na
ByteArray. Na przykład:val activeDataset = "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()fun String.dsToByteArray(): ByteArray { return chunked(2).map { it.toInt(16).toByte() }.toByteArray() }Użyj
fromActiveOperationalDataset, aby utworzyćThreadNetworkCredentials. Jeśli operacja się powiedzie, będziesz mieć dostęp do nazwy sieci Thread, kanału i innych informacji o sieci. Pełną listę właściwości znajdziesz w artykule ThreadNetworkCredentials.val threadNetworkCredentials = ThreadNetworkCredentials.fromActiveOperationalDataset(activeDataset) Log.d( "threadNetworkCredentials", threadNetworkCredentials.channel.toString() + " - " + threadNetworkCredentials.networkName)Wywołaj interfejs API
isPreferredCredentialsi przekaż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}]") }
Dane logowania do sieci Thread według agenta granicznego
Identyfikator agenta granicznego jednoznacznie identyfikuje urządzenie TBR. Aby użyć interfejsu API getCredentialsByBorderAgent, musisz najpierw utworzyć obiekt ThreadBorderAgent i przekazać identyfikator agenta granicznego.
Po utworzeniu obiektu ThreadBorderAgent wywołaj getCredentialsByBorderAgent. Jeśli dane logowania zostały zapisane, sprawdź, czy są preferowane.
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}]") }
}
Dane logowania do sieci Thread według rozszerzonego identyfikatora PAN
Podobnie jak w przypadku getPreferredCredentials, możesz też poprosić użytkownika o
dane logowania z TBR's rozszerzonego identyfikatora PAN. Gdy użytkownik zatwierdzi, getCredentialsByExtendedPanId zwróci IntentSender, a wynik aktywności będzie zawierać obiekt ThreadNetworkCredentials.
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}]") }
}
Usuwanie danych logowania
Gdy urządzenie border router zostanie usunięte z domu lub przywrócone do ustawień fabrycznych, musisz usunąć jego sieć Thread z usług Google Play.
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}]") }
}
Zasoby
Więcej informacji o pakiecie SDK sieci Thread znajdziesz w dokumentacji interfejsu API.