L'SDK Thread Network fornisce funzionalità simili a un portachiavi digitale, consentendo alle tue app Android di condividere le credenziali di rete Thread con Google Play Services. In questo modo, le tue app possono configurare qualsiasi dispositivo Thread da qualsiasi ecosistema di smart home, senza esporre direttamente le credenziali e i dati utente.
Con poche chiamate API, puoi:
- Richiedere le credenziali di rete Thread preferite a Google Play Services.
- Configurare nuovi Thread Border Router (TBR) e aggiungere le credenziali di rete Thread a Google Play Services.
- Se hai già TBR sul campo, puoi verificare se i tuoi TBR si trovano nella rete preferita ed eseguirne la migrazione, se necessario.
Esistono diversi percorsi utente e sviluppatore da considerare. In questa guida ne esamineremo la maggior parte, insieme ad altre funzionalità chiave e all'utilizzo consigliato.
Terminologia chiave e concetti API
Prima di iniziare, è utile comprendere i seguenti termini:
Credenziali di rete Thread: blob binario di TLV Thread che codifica il nome della rete Thread, la chiave di rete e altre proprietà richieste da un dispositivo Thread per accedere a una determinata rete Thread.
Credenziali di rete Thread preferite: le credenziali di rete Thread selezionate automaticamente che possono essere condivise con le app di diversi fornitori utilizzando l'API
getPreferredCredentials.ID agente di confine: un ID univoco globale di 16 byte per un TBR dispositivo. Questo ID viene creato e gestito dai fornitori border router.
TBR app di configurazione: è la tua app per Android che configura i nuovi dispositivi TBR e aggiunge le credenziali di rete Thread a Google Play Services. La tua app è il proprietario autorevole delle credenziali aggiunte e ha accesso a queste.
Molte API Thread Network restituiscono un' attività che viene completata in modo asincrono. Puoi utilizzare addOnSuccessListener e addOnFailureListener per registrare i callback per ricevere il risultato. Per saperne di più, consulta la documentazione relativa all'attività.
Proprietà e manutenzione delle credenziali
L'app che aggiunge le credenziali di rete Thread diventa il proprietario delle credenziali e dispone delle autorizzazioni complete per accedervi. Se provi ad accedere alle credenziali aggiunte da altre app, riceverai un errore PERMISSION_DENIED.
In qualità di proprietario dell'app, ti consigliamo di mantenere aggiornate le credenziali memorizzate in Google Play Services quando la rete TBR viene aggiornata. Ciò significa aggiungere le credenziali quando necessario, aggiornarle quando le border router's credenziali di rete Thread cambiano e rimuovere le credenziali quando il TBR viene rimosso o vengono ripristinati i dati di fabbrica.
Rilevamento dell'agente di confine
Le credenziali devono essere salvate con un ID agente di confine. Dovrai assicurarti che la tua app di configurazione TBR sia in grado di determinare gli ID agente di confine dei tuoi TBRs.
TBRs devono utilizzare mDNS per pubblicizzare le informazioni sulla rete Thread,
inclusi il nome della rete, l'ID PAN esteso e l'ID agente di confine. I valori txt corrispondenti per questi attributi sono rispettivamente nn, xp e id.
Per le reti con Google Thread Border Router (gTBR)s, Google Play Services ottiene automaticamente le credenziali di rete Thread Google da utilizzare.
Integra l'SDK nella tua app per Android
Per iniziare, completa i seguenti passaggi:
Segui le istruzioni fornite in Configura Google Play Services.
Aggiungi la dipendenza di Google Play Services al file
build.gradle:implementation 'com.google.android.gms:play-services-threadnetwork:16.2.1'Facoltativo: definisci una classe di dati
BorderAgentper archiviare TBR informazioni. Utilizzeremo questi dati in questa guida:data class BorderAgentInfo( // Network Name max 16 len val networkName: String = "", val extPanId: ByteArray = ByteArray(16), val borderAgentId: ByteArray = ByteArray(16), ... )
Successivamente, esamineremo i passaggi consigliati per aggiungere e gestire le credenziali preferite.
Nuove configurazioni del router di confine Thread
Prima di creare una nuova rete per i nuovi router di confine, è importante provare a utilizzare prima le credenziali di rete preferite. In questo modo, i dispositivi Thread vengono connessi a una singola rete Thread, se possibile.
Una chiamata a getPreferredCredentials avvia un'attività, chiedendo agli utenti di consentire la richiesta di rete. Se le credenziali di rete sono state memorizzate nel portachiavi digitale dell'SDK Thread, vengono restituite alla tua app.
Richiedi credenziali
Per chiedere all'utente le credenziali preferite:
Dichiara un
ActivityLauncher:private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>Gestisci il risultato dell'attività, restituito come
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.") } }Se stai configurando un nuovo TBR, ti consigliamo di chiamare
preferredCredentialse avviare l'attività. Questa chiamata garantirà che il nuovo TBR utilizzi le stesse credenziali già memorizzate come preferite nello smartphone, promuovendo la convergenza di diversi TBR nella stessa rete.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}]") } }Se il tuo caso d'uso riguarda la configurazione di dispositivi non TBR, ad esempio un nuovo dispositivo finale Matter-over-Thread, ti consigliamo di utilizzare l'API
allActiveCredentialsper recuperare le credenziali. Questa chiamata eseguirà la scansione dei TBR trovati nella rete locale e pertanto non restituirà le credenziali non disponibili da un TBR esistente a livello locale.// 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 }
Crea una nuova rete Thread
Se in una rete Thread di un utente non sono disponibili credenziali di rete Thread preferite o credenziali Thread attive, puoi utilizzare l'API addCredentials per aggiungere le credenziali a Google Play Services. Per farlo, devi creare un ThreadBorderAgent e fornire anche un oggetto ThreadNetworkCredentials.
Per creare una rete casuale, chiama newRandomizeBuilder:
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder().build()
Per specificare il nome della rete Thread:
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder()
.setNetworkName("ThreadNetworkSDK")
.build()
Aggiungi credenziali
Per rendere disponibili le credenziali di rete Thread per altri fornitori di Thread, dobbiamo aggiungerle a Google Play Services. Prima di poter aggiungere le nuove credenziali, dobbiamo anche sapere a quale TBR dispositivo TBR appartiene questa rete Thread.
In questo esempio, creeremo un ThreadBorderAgent da un ID agente di confine e passeremo le nuove credenziali di rete Thread appena create:
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}]") }
}
Rileva ed esegui la migrazione dei border router sul campo
Se hai border router sul campo, puoi utilizzare
isPreferredCredentials per determinare se i tuoi border router appartengono
alla rete preferita. Questa API non chiede all'
utente l'autorizzazione e controlla le border routercredenziali rispetto a
quelle memorizzate in Google Play Services.
isPreferredCredentials restituisce 0 per la mancata corrispondenza e 1 per la corrispondenza, come tipo di dati Int. Puoi utilizzare IsPreferredCredentialsResult per controllare i risultati.
public @interface IsPreferredCredentialsResult {
int PREFERRED_CREDENTIALS_NOT_FOUND = -1;
int PREFERRED_CREDENTIALS_NOT_MATCHED = 0;
int PREFERRED_CREDENTIALS_MATCHED = 1;
}
Per utilizzare isPreferredCredentials, devi prima creare un oggetto ThreadNetworkCredentials. Esistono diversi modi per creare un'istanza di ThreadNetworkCredentials. Nei passaggi successivi, esamineremo queste opzioni.
Credenziali di rete Thread per set di dati operativi
In alcuni casi, il tuo TBR è già configurato con una
rete Thread e vuoi aggiungere questa rete Thread a Google Play Services
per condividerla con altri fornitori. Puoi creare un'istanza ThreadNetworkCredential da un elenco TLV del set di dati operativi attivi di Thread non elaborati:
Converti il set di dati operativi in un
ByteArray. Ad esempio:val activeDataset = "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()fun String.dsToByteArray(): ByteArray { return chunked(2).map { it.toInt(16).toByte() }.toByteArray() }Utilizza
fromActiveOperationalDatasetper creareThreadNetworkCredentials. Se l'operazione va a buon fine, potrai ottenere il nome della rete Thread, il canale e altre informazioni sulla rete. Per un elenco completo delle proprietà, consulta ThreadNetworkCredentials.val threadNetworkCredentials = ThreadNetworkCredentials.fromActiveOperationalDataset(activeDataset) Log.d( "threadNetworkCredentials", threadNetworkCredentials.channel.toString() + " - " + threadNetworkCredentials.networkName)Chiama l'API
isPreferredCredentialse passaThreadNetworkCredentials.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}]") }
Credenziali di rete Thread per agente di confine
Un ID agente di confine identifica in modo univoco un TBR dispositivo. Per utilizzare l'API getCredentialsByBorderAgent, devi prima creare un oggetto ThreadBorderAgent e passare l'ID agente di confine.
Dopo aver creato l'oggetto ThreadBorderAgent, chiama getCredentialsByBorderAgent. Se le credenziali sono state salvate, controlla se sono preferite.
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}]") }
}
Credenziali di rete Thread per ID PAN esteso
Analogamente a getPreferredCredentials, puoi anche chiedere all'utente le
credenziali dall'ID PAN esteso di un TBR. getCredentialsByExtendedPanId restituisce un IntentSender e il risultato dell'attività contiene un oggetto ThreadNetworkCredentials quando l'utente approva.
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}]") }
}
Rimuovi credenziali
Quando il dispositivo border router viene rimosso dalla casa o vengono ripristinati i dati di fabbrica, devi rimuovere la rete Thread da Google Play Services.
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}]") }
}
Risorse
Per saperne di più sull'SDK Thread Network, consulta il riferimento API.