L'SDK di rete Thread fornisce funzionalità simili a una portachiavi digitale, consentendo alle 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:
- Richiedi le credenziali di rete Thread preferite da Google Play Services.
- Configura nuovi router di confine e aggiungi le tue 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.
Devi prendere in considerazione diversi percorsi degli utenti e degli sviluppatori. Ne tratteremo la maggior parte in questa guida, insieme ad altre funzionalità chiave e ai dati consigliati per l'utilizzo.
Concetti chiave sulla terminologia e sulle API
Prima di iniziare, è utile comprendere i seguenti termini:
Credenziali di rete Thread: blob binario di TLV di Thread che codificano il nome di rete Thread, la chiave di rete e altre proprietà richieste da un dispositivo Thread per partecipare 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 viene creato e gestito dai fornitori di router di confine.
App Configurazione router di confine Thread: questa è la tua app per Android che configura i nuovi dispositivi Router di confine Thread e aggiunge le credenziali di rete Thread ai servizi Google Play. L'app è il proprietario autore delle credenziali aggiunte e vi ha accesso.
Molte delle API Thread Network restituiscono una Attività completata in modo asincrono. Puoi utilizzare addOnSuccess listener e addOnFailure listener per registrare i callback per la ricezione del risultato. Per ulteriori informazioni, 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 ha le autorizzazioni complete per accedervi. Se tenti di accedere alle credenziali aggiunte da altre app, riceverai un errore PERMISSION_DENIED
.
Come proprietario dell'app, ti consigliamo di mantenere aggiornate le credenziali in Google Play Services quando viene aggiornata la rete del router di confine Thread. Ciò significa aggiungere credenziali quando necessario, aggiornare le credenziali quando cambiano le credenziali di rete Thread del router di confine e rimuovere le credenziali quando il router di confine Thread viene rimosso o ripristinato ai dati di fabbrica.
Rilevamento dell'agente di confine
Le credenziali devono essere salvate con un ID agente di confine. Devi assicurarti che l'app di configurazione del router di confine Thread sia in grado di determinare gli ID dell'agente di confine dei tuoi router di confine Thread.
I router di confine Thread devono utilizzare mDNS per pubblicizzare le informazioni di rete Thread,
tra cui Network Name, Extended Pan ID e Border Agent ID. I valori txt
corrispondenti per questi attributi sono nn
, xp
e id
, rispettivamente.
Per le reti con router di confine Google, Google Play Services riceve automaticamente le credenziali di rete di Google Thread per l'utilizzo.
Integra l'SDK nella tua app per Android
Per iniziare, completa i seguenti passaggi:
Segui le istruzioni fornite in Configurare Google Play Services.
Aggiungi la dipendenza Google Play Services al 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.
Nuove configurazioni del router di confine
Prima di creare una nuova rete per i nuovi router di confine, è importante provare a utilizzare le credenziali di rete preferite. In questo modo, i dispositivi Thread sono connessi a una singola rete Thread, quando possibile.
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, 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.") } }
Chiama il numero
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}]") } }
Creare una nuova rete Thread
Se nella rete Thread di un utente non sono disponibili credenziali di rete Thread preferite, puoi utilizzare l'API addCredentials
per aggiungere credenziali a
Google Play Services. Per farlo, dovrai 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 ad 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 a questa rete Thread.
In questo esempio creeremo un ThreadBorderAgent
da un ID agente di confine e trasferiamo 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 attualmente disponi di router di confine sul campo, puoi utilizzare
isPreferredCredentials
per determinare se appartengono a una rete preferita. Questa API non richiede l'autorizzazione all'utente e controlla le credenziali del router di confine in base a quanto archiviato
in Google Play Services.
isPreferredCredentails
restituisce 0
per i tipi senza dati e 1
per quelli corrispondenti, come tipo di dati Int
. Puoi usare 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 ThreadNetworkCredentials
. Nei passaggi successivi, esamineremo queste opzioni.
Thread credenziali di rete per set di dati operativi
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 dati attivi attivi 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() }
Usa
fromActiveOperationalDataset
per creareThreadNetworkCredentials
. Se l'operazione riesce, potrai recuperare il nome, il canale e altre informazioni sulla rete 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 superaThreadNetworkCredentials
.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 credenziali di rete da Border Agent
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 trasmettere 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 pan esteso
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 dispositivo router di confine viene rimosso dalla casa 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.