A API
MessageClient
pode ser usada para enviar mensagens e anexar os itens abaixo a elas:
- Um payload arbitrário opcional
- Um caminho que identifique de forma exclusiva a ação da mensagem.
Ao contrário do caso de itens de dados, não ocorre sincronização entre os apps de dispositivos móveis e de wearables. As mensagens são um mecanismo de comunicação unidirecional útil para chamadas de procedimento remoto (RPC), como uma mensagem enviada ao wearable para iniciar uma atividade.
Vários dispositivos wearable podem ser conectados ao dispositivo portátil de um usuário. Cada dispositivo conectado à rede é considerado um nó.
Com vários dispositivos conectados, você precisa considerar quais nós recebem as mensagens. Por exemplo, em um app de transcrição de voz que recebe dados de voz no dispositivo wearable, envie a mensagem para um nó com o poder de processamento e a capacidade de bateria para processar a solicitação, como um dispositivo portátil.
Observação: ao especificar os detalhes da mensagem, considere a possibilidade de existirem vários nós conectados. Garanta que a mensagem seja entregue aos dispositivos ou nós esperados.
Consulte o app de exemplo abaixo para conferir exemplos de uso: Camada de dados
Enviar uma mensagem
Um app para wearables pode fornecer funcionalidade para os usuários, como a transcrição de voz. O usuário pode falar no microfone do dispositivo wearable e ter a transcrição salva em formato de nota. Como um dispositivo wearable normalmente não tem o poder de processamento e a capacidade da bateria necessários para processar a atividade de transcrição de voz, o app precisa transferir esse trabalho para um dispositivo conectado mais potente.
As próximas seções mostram como anunciar nós de dispositivos que podem processar solicitações de atividades, descobrir os nós capazes de atender uma necessidade de solicitação e enviar mensagens para esses nós.
Anunciar recursos
Para iniciar uma atividade em um dispositivo portátil usando um wearable, use a
classe
MessageClient
para enviar a solicitação. Como vários wearables
podem ser conectados ao
dispositivo portátil, o app para wearables precisa determinar se um nó conectado é
capaz de iniciar a atividade. No app para dispositivos portáteis, anuncie que o nó
em que ele é executado tem recursos específicos.
Para anunciar os recursos do app para dispositivos portáteis, faça o seguinte:
- Crie um arquivo de configuração XML no diretório
res/values/
do seu projeto e dê o nomewear.xml
a ele. - Adicione um recurso com o nome
android_wear_capabilities
ao arquivowear.xml
. - Defina os recursos que o dispositivo oferece.
Observação: recursos são strings personalizadas que você define e precisam ser únicos dentro do app.
O exemplo abaixo mostra como adicionar um recurso com o nome voice_transcription
ao arquivo
wear.xml
:
<resources xmlns:tools="http://schemas.android.com/tools" tools:keep="@array/android_wear_capabilities"> <string-array name="android_wear_capabilities"> <item>voice_transcription</item> </string-array> </resources>
Extrair nós com os recursos necessários
Inicialmente, você pode detectar os nós compatíveis chamando o
método getCapability
da
classe
CapabilityClient
. Para usar esse método, o app para Wear OS e o app para smartphones
precisam ter o mesmo ID do aplicativo. O exemplo abaixo
mostra como extrair manualmente os resultados dos nós ao alcance com o
recurso voice_transcription
:
Kotlin
private const val VOICE_TRANSCRIPTION_CAPABILITY_NAME = "voice_transcription" ... private fun setupVoiceTranscription() { val capabilityInfo: CapabilityInfo = Tasks.await( Wearable.getCapabilityClient(context) .getCapability( VOICE_TRANSCRIPTION_CAPABILITY_NAME, CapabilityClient.FILTER_REACHABLE ) ) // capabilityInfo has the reachable nodes with the transcription capability updateTranscriptionCapability(capabilityInfo) }
Java
private static final String VOICE_TRANSCRIPTION_CAPABILITY_NAME = "voice_transcription"; ... private void setupVoiceTranscription() { CapabilityInfo capabilityInfo = Tasks.await( Wearable.getCapabilityClient(context).getCapability( VOICE_TRANSCRIPTION_CAPABILITY_NAME, CapabilityClient.FILTER_REACHABLE)); // capabilityInfo has the reachable nodes with the transcription capability updateTranscriptionCapability(capabilityInfo); }
Para detectar nós compatíveis conforme eles forem conectados ao dispositivo wearable, registre uma
instância de um listener, mais especificamente, um OnCapabilityChangedListener
de um objeto CapabilityClient
. O exemplo abaixo mostra como
registrar o listener e extrair um resultado com nós ao alcance que têm o
recurso voice_transcription
:
Kotlin
private fun setupVoiceTranscription() { updateTranscriptionCapability(capabilityInfo).also { capabilityListener -> Wearable.getCapabilityClient(context).addListener( capabilityListener, VOICE_TRANSCRIPTION_CAPABILITY_NAME ) } }
Java
private void setupVoiceTranscription() { ... // This example uses a Java 8 Lambda. You can use named or anonymous classes. CapabilityClient.OnCapabilityChangedListener capabilityListener = capabilityInfo -> { updateTranscriptionCapability(capabilityInfo); }; Wearable.getCapabilityClient(context).addListener( capabilityListener, VOICE_TRANSCRIPTION_CAPABILITY_NAME); }
Depois de detectar os nós compatíveis, determine o destino da mensagem. Escolha um nó
que esteja próximo ao seu dispositivo wearable para minimizar
o roteamento de mensagens por vários nós. Um nó próximo é um nó que está diretamente
conectado ao dispositivo. Para determinar se um nó está próximo (por exemplo, conectado via Bluetooth), chame o método
Node.isNearby()
. Se houver mais de um nó próximo, escolha um arbitrariamente.
Da mesma forma, se houver um nó compatível por perto, escolha um arbitrariamente.
O exemplo abaixo mostra como você pode determinar o melhor nó para usar:
Kotlin
private var transcriptionNodeId: String? = null private fun updateTranscriptionCapability(capabilityInfo: CapabilityInfo) { transcriptionNodeId = pickBestNodeId(capabilityInfo.nodes) } private fun pickBestNodeId(nodes: Set<Node>): String? { // Find a nearby node or pick one arbitrarily. return nodes.firstOrNull { it.isNearby }?.id ?: nodes.firstOrNull()?.id }
Java
private String transcriptionNodeId = null; private void updateTranscriptionCapability(CapabilityInfo capabilityInfo) { Set<Node> connectedNodes = capabilityInfo.getNodes(); transcriptionNodeId = pickBestNodeId(connectedNodes); } private String pickBestNodeId(Set<Node> nodes) { String bestNodeId = null; // Find a nearby node or pick one arbitrarily. for (Node node : nodes) { if (node.isNearby()) { return node.getId(); } bestNodeId = node.getId(); } return bestNodeId; }
Entregar a mensagem
Depois de identificar um nó para usar, envie a mensagem usando a classe
MessageClient
.
O exemplo abaixo mostra como enviar uma mensagem para o nó compatível com transcrições usando um dispositivo wearable. Essa chamada é síncrona e bloqueia o processamento até o sistema colocar a mensagem na fila de entrega.
Observação: um código de resultado bem-sucedido não garante a entrega
da mensagem. Se o app exigir confiabilidade de dados, use objetos
DataItem
ou a classe ChannelClient
para enviar dados entre dispositivos.
Kotlin
const val VOICE_TRANSCRIPTION_MESSAGE_PATH = "/voice_transcription" ... private fun requestTranscription(voiceData: ByteArray) { transcriptionNodeId?.also { nodeId -> val sendTask: Task<*> = Wearable.getMessageClient(context).sendMessage( nodeId, VOICE_TRANSCRIPTION_MESSAGE_PATH, voiceData ).apply { addOnSuccessListener { ... } addOnFailureListener { ... } } } }
Java
public static final String VOICE_TRANSCRIPTION_MESSAGE_PATH = "/voice_transcription"; private void requestTranscription(byte[] voiceData) { if (transcriptionNodeId != null) { Task<Integer> sendTask = Wearable.getMessageClient(context).sendMessage( transcriptionNodeId, VOICE_TRANSCRIPTION_MESSAGE_PATH, voiceData); // You can add success and/or failure listeners, // Or you can call Tasks.await() and catch ExecutionException sendTask.addOnSuccessListener(...); sendTask.addOnFailureListener(...); } else { // Unable to retrieve node with transcription capability } }
Observação: para saber mais sobre chamadas síncronas e assíncronas para o Google Play Services e quando usar cada uma delas, consulte a API Tasks.
Você também pode transmitir mensagens para todos os nós conectados. Para extrair todos os nós conectados aos quais você pode enviar mensagens, implemente o código abaixo:
Kotlin
private fun getNodes(): Collection<String> { return Tasks.await(Wearable.getNodeClient(context).connectedNodes).map { it.id } }
Java
private Collection<String> getNodes() { HashSet <String>results = new HashSet<String>(); List<Node> nodes = Tasks.await(Wearable.getNodeClient(context).getConnectedNodes()); for (Node node : nodes.getNodes()) { results.add(node.getId()); } return results; }
Receber uma mensagem
Para mostrar notificações de mensagens recebidas, implemente a
interface
MessageClient.OnMessageReceivedListener
para fornecer um listener para eventos de mensagem. Em seguida, registre o listener
com o método
addListener
. O exemplo abaixo mostra como implementar o listener para verificar o
VOICE_TRANSCRIPTION_MESSAGE_PATH
. Se essa condição for
true
, inicie uma atividade para processar os dados de voz.
Kotlin
fun onMessageReceived(messageEvent: MessageEvent) { if (messageEvent.path == VOICE_TRANSCRIPTION_MESSAGE_PATH) { val startIntent = Intent(this, MainActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) putExtra("VOICE_DATA", messageEvent.data) } startActivity(this, startIntent) } }
Java
@Override public void onMessageReceived(MessageEvent messageEvent) { if (messageEvent.getPath().equals(VOICE_TRANSCRIPTION_MESSAGE_PATH)) { Intent startIntent = new Intent(this, MainActivity.class); startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startIntent.putExtra("VOICE_DATA", messageEvent.getData()); startActivity(this, startIntent); } }
Esse código requer mais detalhes de implementação. Aprenda como implementar uma atividade ou um serviço completo de listener em Ouvir eventos de camada de dados.