O SDK da rede Thread oferece funcionalidade semelhante a um conjunto de chaves digital, permitindo que seus apps Android compartilhem credenciais de rede Thread com o Google Play Services. 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:
- Solicite as credenciais de rede Thread preferidas do Google Play Services.
- Configure novos roteadores de borda e adicione suas credenciais de rede Thread ao Google Play Services.
- Se você já tiver roteadores de borda em campo, verifique se eles estão na rede preferencial e migre-os, se necessário.
Há várias jornadas de usuário e desenvolvedor a serem consideradas. Abordaremos a maioria deles neste guia, além de outros recursos importantes e o uso recomendado.
Terminologia principal e conceitos de API
Antes de começar, é importante entender os seguintes termos:
Credenciais da rede Thread:blob binário de TLVs da linha de execução que codifica o nome, a chave da rede e outras propriedades exigidas por um dispositivo para ingressar em uma determinada rede.
Credenciais preferidas da rede Thread: as credenciais da rede Thread selecionadas que podem ser compartilhadas com apps de diferentes fornecedores usando a API
getPreferredCredentials
.Border Agent ID: um código globalmente exclusivo de 16 bytes para um dispositivo Thread Border Router. Esse ID é criado e gerenciado por fornecedores de roteadores de borda.
App de configuração do roteador de borda do Thread:esse é seu app Android que configura novos dispositivos e adiciona as credenciais de rede do Thread ao Google Play Services. O aplicativo é o proprietário autoritativo das credenciais adicionadas e tem acesso a elas.
Muitas das APIs Thread Network retornam uma Tarefa que é concluída de forma assíncrona. Você pode usar addOnSuccessListener e addOnFailureListener para registrar retornos de chamada para receber o resultado. Para saber mais, consulte a documentação da Tarefa.
Propriedade e manutenção de credenciais
O app que adiciona as credenciais de rede Thread se torna o proprietário das
credenciais e tem permissões totais para acessar as credenciais. Se você tentar
acessar as credenciais adicionadas por outros apps, receberá um erro
PERMISSION_DENIED
.
Como proprietário do app, é recomendável manter as credenciais armazenadas no Google Play Services atualizadas quando a rede do roteador de borda do Thread for 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 original.
Descoberta do agente de borda
As credenciais precisam ser salvas com um ID de agente de borda. Você precisa garantir que o app Thread Border Router Setup possa determinar os IDs do agente de borda dos seus roteadores de borda do Thread.
Os roteadores de borda do Thread precisam usar o mDNS para divulgar informações da rede Thread,
incluindo o nome da rede, o código do Panorâmica estendida e o código do agente do Border. Os valores txt
correspondentes para esses atributos são nn
, xp
e id
, respectivamente.
Para redes com roteadores de borda do Google, o Google Play Services recebe automaticamente as credenciais de rede do Google Thread para uso.
Integrar o SDK ao seu app Android
Para começar, siga estas etapas:
Siga as instruções fornecidas 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.0.0'
Opcional: defina uma classe de dados
BorderAgent
para armazenar informações do roteador de borda. Usaremos esses 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, abordaremos as etapas recomendadas para adicionar e gerenciar credenciais preferidas.
Novas configurações do roteador de borda
Antes de criar uma nova rede para novos roteadores de borda, é importante tentar usar as credenciais de rede preferenciais primeiro. Isso garante que os dispositivos Thread estejam conectados a uma única rede Thread quando possível.
Uma chamada para getPreferredCredentials
inicia
uma atividade, solicitando que os usuários permitam a solicitação de rede. Se as credenciais de rede
forem armazenadas no conjunto de chaves digitais do SDK do Thread, elas
serão retornadas ao app.
Solicitar credenciais
Para solicitar ao usuário as credenciais preferidas:
Declare um
ActivityLauncher
:private lateinit var preferredCredentialsLauncher: ActivityResultLauncher<IntentSenderRequest>
Processe 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.") } }
Chame
preferredCredentials
e inicie a atividade: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}]") } }
Criar uma nova rede Thread
Se não houver credenciais de rede Thread preferidas disponíveis na rede Thread
de um usuário, você poderá usar a API addCredentials
para adicionar credenciais ao
Google Play Services. Para fazer isso, você precisará criar um ThreadBorderAgent
e também 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 as credenciais da rede Thread para outros fornecedores, precisamos adicioná-las ao Google Play Services. Antes de adicionarmos nossas novas credenciais, também precisamos saber a qual dispositivo de roteador de borda essa rede Thread pertence.
Neste exemplo, criaremos um ThreadBorderAgent
com base em um ID do agente de borda e
transmitiremos 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 em campo
Se você tiver roteadores de borda em 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 no Google Play Services.
isPreferredCredentails
retorna 0
para não correspondentes e 1
para correspondência como um tipo de dados Int
. Use IsPreferredCredentialsResult
para verificar os resultados.
public @interface IsPreferredCredentialsResult {
int PREFERRED_CREDENTIALS_NOT_FOUND = -1;
int PREFERRED_CREDENTIALS_NOT_MATCHED = 0;
int PREFERRED_CREDENTIALS_MATCHED = 1;
}
Para usar isPreferredCredentials
, você precisa criar um objeto ThreadNetworkCredentials
primeiro. Há várias maneiras de instanciar ThreadNetworkCredentials
. Nas próximas etapas, analisaremos essas opções.
Thread credenciais de rede por conjunto de dados operacional
Há casos em que seu roteador de borda Thread já está configurado com uma
rede Thread e você quer adicionar essa rede Thread ao Google Play Services
para compartilhá-la com outros fornecedores. Você pode criar uma instância de ThreadNetworkCredential
a partir de uma lista bruta de TLV do conjunto de dados operacional ativo:
Converta o conjunto de dados operacional em um
ByteArray
. Por exemplo:val activeDataset = "0e080000000000010000000300000f35060004001fffe0020833333333...".dsToByteArray()
fun String.dsToByteArray(): ByteArray { return chunked(2).map { it.toInt(16).toByte() }.toByteArray() }
Use
fromActiveOperationalDataset
para criar oThreadNetworkCredentials
. Quando bem-sucedido, você poderá ver o nome, o canal e outras informações da rede Thread. Para ver 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 por Border Agent
Um ID do agente de borda identifica exclusivamente um dispositivo de roteador de borda. Para usar
a API getCredentialsByBorderAgent
, primeiro você precisa criar um
objeto ThreadBorderAgent
e transmitir o ID do agente de borda.
Depois de criar o objeto ThreadBorderAgent
, chame getCredentialsByBorderAgent
. Se as credenciais foram salvas, verifique se elas são preferenciais.
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 Thread credenciais por código de extensão estendida
Assim como em getPreferredCredentials
, você também pode solicitar ao usuário
credenciais do ID do painel estendido do roteador de borda. O
getCredentialsByExtendedPanId
retorna um IntentSender
, e o resultado da atividade
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 do roteador de borda é removido da casa ou da redefinição para a configuração original, é necessário remover a rede Thread do 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}]") }
}
Recursos
Para saber mais sobre o SDK da Thread Network, consulte a Referência da API.