Invia i messaggi utilizzando l'API
MessageClient
e alleghi i seguenti elementi al messaggio:
- Payload arbitrario facoltativo
- Un percorso che identifica in modo univoco l'azione del messaggio
A differenza degli elementi di dati, non avviene alcuna sincronizzazione tra le app per dispositivi portatili e indossabili. I messaggi sono un meccanismo di comunicazione unidirezionale utile per le chiamate di procedura remota (RPC), come l'invio di un messaggio al dispositivo indossabile per avviare un'attività.
È possibile connettere più dispositivi indossabili al dispositivo portatile di un utente. Ogni dispositivo connesso nella rete è considerato un nodo.
Con più dispositivi connessi, devi considerare quali nodi ricevono i messaggi. Ad esempio, in un'app di trascrizione vocale che riceve dati vocali sul dispositivo indossabile, invia il messaggio a un nodo con la potenza di elaborazione e la capacità della batteria per gestire la richiesta, ad esempio un dispositivo portatile.
Nota: quando specifichi i dettagli del messaggio, considera la possibilità di avere più nodi connessi. Assicurati che il messaggio venga recapitato ai dispositivi o nodi previsti.
Per esempi di utilizzo, consulta le seguenti app di esempio:
Inviare un messaggio
Un'app indossabile può fornire funzionalità agli utenti, ad esempio la trascrizione vocale. Gli utenti possono parlare al microfono del dispositivo indossabile e visualizzare una trascrizione salvata in una nota. Poiché in genere un dispositivo indossabile non ha la potenza di elaborazione e la capacità della batteria necessarie per gestire l'attività di trascrizione vocale, l'app deve trasferire questa operazione a un dispositivo connesso più capace.
Le sezioni seguenti mostrano come pubblicizzare i nodi di dispositivi in grado di elaborare le richieste di attività, scoprire quali nodi sono in grado di soddisfare un'esigenza richiesta e inviare messaggi a questi nodi.
Pubblicizza le funzionalità
Per avviare un'attività su un dispositivo portatile da un dispositivo indossabile, utilizza la classe
MessageClient
per inviare la richiesta. Dal momento che è possibile connettere più dispositivi indossabili al dispositivo portatile, l'app indossabile deve determinare che un nodo connesso è in grado di avviare l'attività. Nell'app portatile, fai sapere che il nodo
su cui viene eseguito offre funzionalità specifiche.
Per pubblicizzare le funzionalità della tua app portatile:
- Crea un file di configurazione XML nella directory
res/values/
del progetto e assegnagli il nomewear.xml
. - Aggiungi una risorsa denominata
android_wear_capabilities
awear.xml
. - Definisci le funzionalità fornite dal dispositivo.
Nota: le funzionalità sono stringhe personalizzate che definisci e devono essere univoche all'interno dell'app.
L'esempio seguente mostra come aggiungere una funzionalità denominata voice_transcription
a 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>
Recupera i nodi con le funzionalità richieste
Inizialmente, puoi rilevare i nodi idonei chiamando il metodo getCapability
della classe
CapabilityClient
. Per utilizzare questo metodo, l'app per Wear OS e l'app Telefono devono avere lo stesso ID applicazione. L'esempio seguente mostra come recuperare manualmente i risultati dei nodi raggiungibili con la funzionalità 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); }
Per rilevare i nodi idonei quando si connettono al dispositivo indossabile, registra un'istanza di un listener, in particolare un OnCapabilityChangedListener
di un oggetto CapabilityClient
. L'esempio seguente mostra come registrare il listener e recuperare un risultato con nodi raggiungibili che hanno la funzionalità 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); }
Dopo aver rilevato i nodi, determina dove inviare il messaggio. Scegli un nodo
che si trovi nelle vicinanze del tuo dispositivo indossabile per ridurre al minimo
il routing dei messaggi attraverso più nodi. Un nodo vicino è definito come un nodo direttamente connesso al dispositivo. Per determinare se un nodo è nelle vicinanze, ad esempio connesso tramite Bluetooth, chiama il metodo
Node.isNearby()
. Se c'è più di un nodo nelle vicinanze, scegline uno in modo arbitrario;
Analogamente, se non c'è nessun nodo idoneo nelle vicinanze, scegline uno in modo arbitrario.
L'esempio seguente mostra come determinare il nodo migliore da utilizzare:
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; }
Trasmetti il messaggio
Dopo aver identificato un nodo da utilizzare, invia il messaggio utilizzando la classe
MessageClient
.
L'esempio seguente mostra come inviare un messaggio al nodo compatibile con la trascrizione da un dispositivo indossabile. Questa chiamata è sincrona e blocca l'elaborazione finché il sistema non mette in coda il messaggio per la consegna.
Nota: un codice risultato riuscito non garantisce la consegna del messaggio. Se la tua app richiede l'affidabilità dei dati, valuta l'utilizzo di oggetti
DataItem
o della classe ChannelClient
per inviare dati da un dispositivo all'altro.
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 } }
Nota: per scoprire di più sulle chiamate asincrone e sincrone a Google Play Services e su quando utilizzarle, consulta l'API Tasks.
Puoi anche trasmettere messaggi a tutti i nodi connessi. Per recuperare tutti i nodi connessi a cui puoi inviare messaggi, implementa il codice seguente:
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; }
Ricevere un messaggio
Per ricevere notifiche dei messaggi ricevuti, implementa l'interfaccia
MessageClient.OnMessageReceivedListener
per fornire un listener per gli eventi dei messaggi. Quindi, registra il listener con il metodo addListener
. L'esempio seguente mostra come implementare il listener per verificare l'elemento
VOICE_TRANSCRIPTION_MESSAGE_PATH
. Se questa condizione è true
, avvia un'attività per elaborare i dati vocali.
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); } }
Questo codice richiede ulteriori dettagli di implementazione. Scopri come implementare un'attività o un servizio listener completo in Ascolta gli eventi del livello dati.