O SDK da rede Thread oferece uma funcionalidade semelhante a um chaveiro digital, permitindo que seus apps Android compartilhem credenciais da rede Thread com os serviços do Google Play. Isso permite que seus apps configurem qualquer dispositivo Thread de qualquer ecossistema de casa inteligente sem expor credenciais e dados do usuário diretamente.
Com apenas algumas chamadas de API, você pode:
- Solicita credenciais da rede Thread preferida do Google Play Services.
- Configure novos roteadores de borda e adicione as credenciais da rede Thread aos Serviços do Google Play.
- Se você já tiver roteadores de borda no campo, verifique se eles estão na rede preferencial e migre-os, se necessário.
Há várias jornadas de usuários e desenvolvedores a serem consideradas. Vamos abordar a maioria deles neste guia, além de outros recursos importantes e o uso recomendado.
Principais termos e conceitos da API
Antes de começar, é útil entender os seguintes termos:
Credenciais de rede do Thread:blob binário de TLVs do Thread que codifica Nome da rede Thread, chave de rede e outras propriedades exigidas pelos um dispositivo Thread para entrar em uma determinada rede Thread.
Credenciais de rede Thread preferidas:a rede Thread selecionada automaticamente credenciais que podem ser compartilhadas com aplicativos de diferentes fornecedores usando o API
getPreferredCredentials
.ID do agente de borda: um ID globalmente exclusivo de 16 bytes para um dispositivo de roteador de borda Thread. Esse ID é criado e gerenciado pelos fornecedores de roteadores de fronteira.
App de configuração do roteador de borda do Thread: é o app Android que configura novos dispositivos de roteador de borda do Thread e adiciona as credenciais da rede Thread ao Google Play Services. Seu app é o proprietário autorizado do credenciais e tem acesso a elas.
Muitas das APIs Thread Network retornam uma Tarefa que é concluído de maneira assíncrona. Você pode usar addOnSuccessListener e addOnFailureListener para registrar callbacks para receber o resultado. Para saber mais, consulte a Tarefa na documentação do Google Cloud.
Propriedade e manutenção das credenciais
O app que adiciona as credenciais da rede Thread se torna o proprietário delas e tem permissões totais para acessar as credenciais. Se você tentar
acessar credenciais adicionadas por outros apps, vai receber um erro
PERMISSION_DENIED
.
Como proprietário do app, recomendamos que você mantenha as credenciais armazenadas no Google Google Play Services atualizado quando a rede do roteador de borda do Thread é atualizada. Isso significa adicionar credenciais quando necessário, atualizar credenciais quando as credenciais da rede Thread do roteador de borda mudarem e remover credenciais quando o roteador de borda Thread for removido ou redefinido para a configuração de fábrica.
Descoberta de agente de borda
As credenciais precisam ser salvas com um ID de agente de fronteira. Você precisará ter certeza de que o app de configuração do roteador de borda do Thread consegue determinar os IDs dos agentes de borda dos roteadores de borda do Thread.
Os roteadores de borda do Thread precisam usar o mDNS para divulgar informações de rede do Thread,
incluindo o Nome da rede, o ID de panorama estendido e o ID do agente de borda. O
valores txt
correspondentes para esses atributos são nn
, xp
e id
,
respectivamente.
Em redes com roteadores de borda do Google, o Google Play Services automaticamente recebe as credenciais da rede do Google Thread para uso.
Integrar o SDK ao seu app Android
Para começar, siga estas etapas:
Siga as instruções em Configurar o Google Play Services.
Adicione a dependência do Google Play Services ao arquivo
build.gradle
:implementation 'com.google.android.gms:play-services-threadnetwork:16.2.1'
Opcional:defina uma classe de dados
BorderAgent
para armazenar o roteador de borda informações imprecisas ou inadequadas. Usaremos estes dados ao longo deste guia:data class BorderAgentInfo( // Network Name max 16 len val networkName: String = "", val extPanId: ByteArray = ByteArray(16), val borderAgentId: ByteArray = ByteArray(16), ... )
Em seguida, veremos as etapas recomendadas para adicionar e gerenciar credenciais.
Novas configurações de roteador de borda
Antes de criar uma nova rede para novos roteadores de borda, é importante tentar usar as credenciais de rede preferidas primeiro. Isso garante que Os dispositivos Thread são conectados a uma única rede Thread quando possível.
Uma chamada para getPreferredCredentials
é iniciada
uma atividade, solicitando que os usuários permitam a solicitação de rede. Se as credenciais
de rede tiverem sido armazenadas no chaveiro digital do SDK do Thread, elas serão
retornadas ao app.
Solicitar credenciais
Para solicitar as credenciais preferidas do usuário:
Declare um
ActivityLauncher
:private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>
Gerencie o resultado da atividade, retornado como
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 você estiver configurando um novo roteador de borda Thread, é recomendável chamar
preferredCredentials
e iniciar a atividade. Essa chamada garante que o novo roteador de borda Thread use as mesmas credenciais já armazenadas como preferencial no smartphone, promovendo a convergência de diferentes TBRs para a mesma rede.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 o caso de uso estiver relacionado à configuração de dispositivos que não são do TBR, como um novo dispositivo final do Matter sobre o Thread, é recomendável usar a API
allActiveCredentials
para buscar credenciais. Esta chamada vai procurar TBRs encontrados na região e, portanto, não retornará credenciais que não estejam disponíveis por uma a TBR existente localmente.// 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 }
Criar uma nova rede Thread
Se não houver credenciais da rede Thread preferida nem credenciais de linha de execução
ativa disponíveis na rede Thread de um usuário, use a API addCredentials
para adicionar credenciais ao
Google Play Services. Para fazer isso, é necessário criar um ThreadBorderAgent
e fornecer um objeto ThreadNetworkCredentials
.
Para criar uma rede aleatória, chame newRandomizeBuilder
:
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder().build()
Para especificar o nome da rede Thread:
val threadCredentials = ThreadNetworkCredentials.newRandomizedBuilder()
.setNetworkName("ThreadNetworkSDK")
.build()
Adicionar credenciais
Para disponibilizar suas credenciais de rede Thread para outros fornecedores, precisamos adicioná-las aos serviços do Google Play. Antes de adicionar nossas novas credenciais, também precisamos saber a qual dispositivo de roteador de borda essa rede Thread pertence.
Neste exemplo, vamos criar um ThreadBorderAgent
usando o ID de um agente de borda.
Passe as novas credenciais da rede Thread que você acabou de criar:
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}]") }
}
Detectar e migrar roteadores de borda no campo
Se você tiver roteadores de borda no campo, use
isPreferredCredentials
para determinar se eles pertencem
à rede preferencial. Essa API não solicita permissão ao
usuário e verifica as credenciais do roteador de borda em relação ao que está armazenado
nos Serviços do Google Play.
isPreferredCredentails
retorna 0
para não correspondência e 1
para
correspondência, como um tipo de dados Int
. Use IsPreferredCredentialsResult
para conferir seus resultados.
public @interface IsPreferredCredentialsResult {
int PREFERRED_CREDENTIALS_NOT_FOUND = -1;
int PREFERRED_CREDENTIALS_NOT_MATCHED = 0;
int PREFERRED_CREDENTIALS_MATCHED = 1;
}
Para usar isPreferredCredentials
, primeiro é necessário criar um
objeto ThreadNetworkCredentials
. Há várias maneiras de instanciar ThreadNetworkCredentials
. Nas próximas etapas, vamos abordar essas opções.
Credenciais da rede Thread por conjunto de dados operacional
Há casos em que o roteador de borda do Thread já está configurado com uma
rede Thread e quer adicioná-la ao Google Play Services
para compartilhá-lo com outros fornecedores. Você pode criar um ThreadNetworkCredential
de uma lista bruta de TLV de conjunto de dados operacional ativo da linha de execução:
Converta o conjunto de dados operacional em um
ByteArray
. Exemplo:val activeDataset = "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()
fun String.dsToByteArray(): ByteArray { return chunked(2).map { it.toInt(16).toByte() }.toByteArray() }
Use
fromActiveOperationalDataset
para criar aThreadNetworkCredentials
. Quando terminar, você poderá conferir o nome, o canal e o nome da rede Thread outras informações de rede. Para uma lista completa de propriedades, consulte ThreadNetworkCredentials.val threadNetworkCredentials = ThreadNetworkCredentials.fromActiveOperationalDataset(activeDataset) Log.d( "threadNetworkCredentials", threadNetworkCredentials.channel.toString() + " - " + threadNetworkCredentials.networkName)
Chame a API
isPreferredCredentials
e transmita oThreadNetworkCredentials
.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}]") }
Credenciais da rede Thread pelo Border Agent
Um ID de agente de borda identifica exclusivamente um dispositivo roteador de borda. Para usar
a API getCredentialsByBorderAgent
, primeiro você precisa criar um
ThreadBorderAgent
e transmita o ID do agente de borda.
Depois de criar o objeto ThreadBorderAgent
, chame
getCredentialsByBorderAgent
. Se as credenciais foram salvas, verifique
se preferirem.
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}]") }
}
Credenciais da rede Thread por ID de PAN estendido
Assim como em getPreferredCredentials
, também é possível solicitar ao usuário
credenciais do ID de panorâmica estendida de um roteador de borda. O
getCredentialsByExtendedPanId
retorna uma IntentSender
, e a atividade
resultado contém um objeto ThreadNetworkCredentials
quando o usuário aprova.
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}]") }
}
Remover credenciais
Quando o dispositivo de roteador de borda for removido da casa ou redefinido para a configuração original, você precisa remover a rede Thread dos Serviços do 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}]") }
}
Recursos
Para saber mais sobre o SDK da rede Thread, consulte a referência da API.