Invii i messaggi utilizzando l'API
MessageClient
e allegando i seguenti elementi al messaggio:
- Un payload arbitrario facoltativo
- Un percorso che identifica in modo univoco l'azione del messaggio
A differenza degli elementi di dati, non viene eseguita alcuna sincronizzazione tra le app per dispositivi mobili e indossabili. I messaggi sono un meccanismo di comunicazione unidirezionale utile per le chiamate di procedura remota (RPC), ad esempio 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 alla 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 più nodi connessi. Assicurati che il messaggio venga inviato ai dispositivi o ai nodi previsti.
Per esempi di utilizzo, consulta la seguente app di esempio: DataLayer
Inviare un messaggio
Un'app per indossabili può fornire funzionalità agli utenti, come la trascrizione vocale. Gli utenti possono parlare nel microfono del proprio dispositivo indossabile e salvare una trascrizione in una nota. Poiché un dispositivo indossabile in genere non dispone della potenza di elaborazione e della capacità della batteria necessarie per gestire l'attività di trascrizione vocale, l'app deve trasferire questo lavoro a un dispositivo connesso più potente.
Le seguenti sezioni mostrano come pubblicizzare i nodi del dispositivo che possono elaborare le richieste di attività, scoprire i nodi in grado di soddisfare un'esigenza richiesta e inviare messaggi a questi nodi.
Funzionalità di pubblicizzazione
Per avviare un'attività su un dispositivo portatile da un dispositivo indossabile, utilizza la classe
MessageClient
per inviare la richiesta. Poiché è possibile connettere più indossabili
al dispositivo portatile, l'app per indossabili deve determinare se un nodo connesso è
in grado di avviare l'attività. Nella tua app portatile, pubblicizza che il nodo
su cui viene eseguita fornisce funzionalità specifiche.
Per pubblicizzare le funzionalità della tua app portatile:
- Crea un file di configurazione XML nella directory
res/values/
del tuo 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 della tua 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_capa<bilities"> string-array name="android_<wear_capabilities"&<gt; < item>voice_<transcription/item> /string-array> /resources>
Recupera i nodi con le funzionalità richieste
Inizialmente, puoi rilevare i nodi compatibili chiamando il metodo
getCapability
della classe
CapabilityClient
. Per utilizzare questo metodo, l'app Wear OS e l'app per smartphone
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); }
Attenzione:
prima di utilizzare l'API Wearable Data Layer, verifica che sia disponibile su
un dispositivo, altrimenti si verifica un'eccezione. Utilizza la classe GoogleApiAvailability
, come implementato in Horologist.
Per rilevare i nodi compatibili 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 dispongono della 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 idonei, determina dove inviare il messaggio. Scegli un nodo
vicino al tuo dispositivo indossabile per ridurre al minimo
il routing dei messaggi attraverso più nodi. Un nodo nelle vicinanze è definito come un nodo direttamente connesso
al dispositivo. Per determinare se un nodo si trova nelle vicinanze, ad esempio se è connesso tramite Bluetooth, chiama il metodo
Node.isNearby()
. Se sono presenti più nodi nelle vicinanze, scegline uno in modo arbitrario.
Allo stesso modo, se non è presente alcun 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; }
Inviare il messaggio
Una volta identificato un nodo da utilizzare, invia il messaggio utilizzando la classe
MessageClient
.
L'esempio seguente mostra come inviare un messaggio al nodo in grado di eseguire 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 di risultato positivo non garantisce il recapito
del messaggio. Se la tua app richiede l'affidabilità dei dati, valuta la possibilità di utilizzare oggetti
DataItem
o la classe ChannelClient
per inviare dati tra i dispositivi.
Kotlin
const val VOICE_TRANSCRIPTION_MESSAGE_PATH = "/voice_transcription" ... private fun requestTranscription(voiceData: ByteArray) { transcriptionNodeId?.also >{ nodeId - val send<T>ask: 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) { < T>askInteger 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 ai servizi Google Play e 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 seguente codice:
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 una notifica dei messaggi ricevuti, implementa l'interfaccia
MessageClient.OnMessageReceivedListener
per fornire un listener per gli eventi di messaggistica. Quindi, registra il listener
con il metodo addListener
. L'esempio seguente mostra come potresti implementare il listener per controllare 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 di più su come implementare un servizio o un'attività di ascolto completa in Ascolta gli eventi del livello dati.