L'SDK di rete Thread fornisce funzionalità simili a un portachiavi digitale, consentendo alle tue app Android di condividere le credenziali di rete di Thread con Google Play Services. In questo modo, le app possono configurare qualsiasi dispositivo Thread da qualsiasi ecosistema per la smart home, senza esporre direttamente credenziali e dati utente.
Con poche chiamate API puoi:
- Richiedere le credenziali di rete preferite per Thread da Google Play Services.
- Configurare nuovi router di confine e aggiungere le credenziali di rete Thread a Google Play Services.
- Se hai già router di confine sul campo, puoi controllare se i tuoi router di confine si trovano nella rete preferita ed eseguirne la migrazione, se necessario.
Esistono diversi percorsi che gli utenti e gli sviluppatori possono prendere in considerazione. Li tratteremo in questa guida, insieme ad altre funzionalità chiave e al loro utilizzo consigliato.
Terminologia e concetti chiave delle API
Prima di iniziare, è utile comprendere i seguenti termini:
Credenziali di rete Thread: blob binario di TLV di Thread che codifica il nome di rete di Thread, la chiave di rete e altre proprietà richieste da un dispositivo Thread per unirsi a una determinata rete Thread.
Credenziali di rete Thread preferite: le credenziali di rete Thread selezionate automaticamente che possono essere condivise con app di fornitori diversi utilizzando l'API
getPreferredCredentials
.ID agente di confine: un ID univoco globale a 16 byte per un dispositivo router di confine Thread. Questo ID è creato e gestito dai fornitori di router di confine.
App Route Border Router: si tratta dell'app per Android che configura i nuovi dispositivi Thread Border Router e aggiunge le credenziali di rete Thread ai servizi Google Play. L'app è la proprietaria autorevole delle credenziali aggiunte e vi ha accesso.
Molte API di rete Thread restituiscono un'attività che viene completata in modo asincrono. Puoi utilizzare addOnSuccessSuccess e addOnFailureAscolta per registrare i callback per la ricezione del risultato. Per scoprire di più, consulta la documentazione di Task.
Proprietà e manutenzione delle credenziali
L'app che aggiunge le credenziali di rete Thread diventa il proprietario delle
credenziali e dispone di autorizzazioni complete per accedervi. Se tenti di 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 archiviate in Google Play Services quando la rete del router di confine Thread viene aggiornata. Ciò significa aggiungere credenziali quando richiesto, aggiornarle quando cambiano le credenziali di rete Thread del router di confine e rimuovere le credenziali quando il router di confine Thread viene rimosso o vengono ripristinati i dati di fabbrica.
Rilevamento dell'agente di confine
Le credenziali devono essere salvate con un ID agente di frontiera. Devi assicurarti che l'app Configurazione del router di confine Thread sia in grado di determinare gli ID degli agenti di confine dei tuoi router di confine Thread.
I router di confine Thread devono utilizzare mDNS per pubblicizzare le informazioni di rete di Thread, tra cui il nome della rete, l'ID Pan esteso e l'ID dell'agente di confine. I valori txt
corrispondenti per questi attributi sono rispettivamente nn
, xp
e id
.
Per le reti con router di confine Google, Google Play Services riceve automaticamente le credenziali di rete Google Thread per l'utilizzo.
Integra l'SDK nella tua app Android
Per iniziare, procedi come indicato di seguito:
Segui le istruzioni fornite nella pagina Configurare Google Play Services.
Aggiungi la dipendenza di Google Play Services al tuo file
build.gradle
:implementation 'com.google.android.gms:play-services-threadnetwork:16.0.0'
Facoltativo: definisci una classe dati
BorderAgent
per archiviare le informazioni del router di confine. In questa guida, utilizzeremo i seguenti dati:data class BorderAgentInfo( // Network Name max 16 len val networkName: String = "", val extPanId: ByteArray = ByteArray(16), val borderAgentId: ByteArray = ByteArray(16), ... )
Quindi, vedremo i passaggi consigliati per aggiungere e gestire le credenziali preferite.
Configurazioni del nuovo router di confine
Prima di creare una nuova rete per i nuovi router di confine, è importante provare a utilizzare prima le credenziali di rete preferite. Ciò garantisce che, quando possibile, i dispositivi Thread siano connessi a una singola rete Thread.
Una chiamata al numero getPreferredCredentials
avvia un'attività, chiedendo agli utenti di consentire la richiesta di rete. Se le credenziali di rete sono state archiviate nel portachiavi digitale dell'SDK Thread, queste vengono restituite alla tua app.
Richiedi credenziali
Per chiedere all'utente le credenziali preferite:
Dichiarare un
ActivityLauncher
:private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>
Gestire il risultato 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.") } }
Chiama
preferredCredentials
e avvia l'attività: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}]") } }
Crea una nuova rete Thread
Se nella rete Thread dell'utente non sono disponibili le credenziali di rete Thread preferite, puoi utilizzare l'API addCredentials
per aggiungere credenziali a
Google Play Services. A questo scopo, 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 tue credenziali di rete Thread per altri fornitori di Thread, dovremo aggiungerle a Google Play Services. Prima di poter aggiungere le nostre nuove credenziali, dobbiamo sapere a quale dispositivo di router di confine appartiene questa rete Thread.
In questo esempio creeremo un ThreadBorderAgent
da un ID agente di confine e passeremo le nuove credenziali di rete Thread che hai appena creato:
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 router di confine sul campo
Se al momento sono presenti router di confine sul campo, puoi utilizzare
isPreferredCredentials
per determinare se i router di confine appartengono alla rete preferita. Questa API non richiede all'utente l'autorizzazione e verifica che le credenziali del router di confine non siano archiviate in Google Play Services.
isPreferredCredentails
restituisce 0
per i valori senza corrispondenza e 1
per i tipi di dati Int
con corrispondenza. 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, vedremo
queste opzioni.
Thread credenziali di rete per set di dati operativo
In alcuni casi, il router di confine Thread è già configurato con una rete Thread e vuoi aggiungerlo a Google Play Services per condividerlo con altri fornitori. Puoi creare un'istanza ThreadNetworkCredential
da un elenco TLV di set di dati operativi Thread non elaborati:
Converti il set di dati operativo in un
ByteArray
. Ad esempio:val activeDataset = "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()
fun String.dsToByteArray(): ByteArray { return chunked(2).map { it.toInt(16).toByte() }.toByteArray() }
Utilizza
fromActiveOperationalDataset
per creareThreadNetworkCredentials
. Se l'operazione ha esito positivo, potrai recuperare il nome, il canale e altre informazioni di rete di Thread. Per un elenco completo delle proprietà, consulta ThreadNetworkCredentials.val threadNetworkCredentials = ThreadNetworkCredentials.fromActiveOperationalDataset(activeDataset) Log.d( "threadNetworkCredentials", threadNetworkCredentials.channel.toString() + " - " + threadNetworkCredentials.networkName)
Chiama l'API
isPreferredCredentials
e supera l'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}]") }
Eseguire il thread delle credenziali di rete in base all'agente di confine
Un ID agente di confine identifica in modo univoco un dispositivo router di confine. 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}]") }
}
Thread credenziali di rete per ID panoramica estesa
Analogamente a getPreferredCredentials
, puoi richiedere all'utente le credenziali dall'ID Pan esteso del router di confine. 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 router di confine viene rimosso da casa tua o dal ripristino dei 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 scoprire di più sull'SDK di rete Thread, consulta la pagina Riferimento API.