Inviare e ricevere messaggi su Wear

Invii i messaggi utilizzando MessageClient e allega 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 app per dispositivi portatili e indossabili. I messaggi sono un meccanismo di comunicazione unidirezionale utile per le chiamate di procedura remota, ad esempio inviando un messaggio all'indossabile per avviare un'attività.

Al dispositivo portatile di un utente possono essere collegati più dispositivi indossabili. Ogni dispositivo connesso in La rete è considerata un nodo.

Con più dispositivi connessi, devi considerare quali i nodi ricevono i messaggi. Ad esempio, in un'app di trascrizione vocale che riceve dati vocali su dispositivo indossabile, inviare il messaggio a un nodo con la potenza di elaborazione e la batteria per gestire la richiesta, ad esempio un dispositivo portatile.

Nota: Quando specifichi i dettagli del tuo messaggio, valuta la possibilità di includere più nodi connessi. Assicurati che il messaggio venga recapitato ai dispositivi o ai nodi previsti.

Fai riferimento alla seguente app di esempio per alcuni esempi di utilizzo: Livello dati

Inviare un messaggio

Un'app indossabile può offrire funzionalità agli utenti, ad esempio la voce della trascrizione. Gli utenti possono parlare al microfono del loro dispositivo indossabile e avere una trascrizione salvato in una nota. Poiché un dispositivo indossabile in genere non ha la potenza di elaborazione e la batteria necessaria per gestire l'attività di trascrizione vocale, l'app deve trasferire questo lavoro a un dispositivo connesso in modo più efficiente.

Le seguenti sezioni mostrano come pubblicizzare i nodi dei dispositivi in grado di elaborare l'attività. le richieste, individuare i nodi in grado di soddisfare un'esigenza e inviare messaggi a nodi.

Per avviare un'attività su un dispositivo portatile da un dispositivo indossabile, utilizza l'icona MessageClient corso per inviare la richiesta. Dato che l'uso di più dispositivi indossabili può essere collegato dispositivo portatile, l'app indossabile deve determinare che un nodo connesso in grado di avviare l'attività. Nell'app portatile, annuncia che il nodo su cui viene eseguito offre funzionalità specifiche.

Per pubblicizzare le funzionalità della tua app portatile:

  1. Crea un file di configurazione XML nella directory res/values/ del tuo progetto. assegna il nome wear.xml.
  2. Aggiungi una risorsa denominata android_wear_capabilities a wear.xml.
  3. Definisci le funzionalità fornite dal dispositivo.

Nota: Le funzionalità sono stringhe personalizzate definite da te 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 capacità richieste

Inizialmente, puoi rilevare i nodi idonei richiamando il metodo Metodo getCapability del CapabilityClient corso. Per usare questo metodo, le app per Wear OS e per smartphone devono avere lo stesso ID applicazione. Nell'esempio che segue mostra come recuperare manualmente i risultati dei nodi raggiungibili con 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 compatibili quando si connettono al dispositivo indossabile, registra un 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 i nodi raggiungibili che hanno 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 vicini al dispositivo indossabile per ridurre al minimo l'instradamento dei messaggi attraverso più nodi. Un nodo nelle vicinanze è definito come un nodo direttamente connesso al dispositivo. Per determinare se c'è un nodo nelle vicinanze, ad esempio connesso tramite Bluetooth, chiama il Node.isNearby(). Se ci sono più nodi nelle vicinanze, scegline uno arbitrariamente; in modo analogo, se nelle vicinanze non è presente nessun nodo abilitato, scegline uno arbitrariamente.

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

Una volta identificato il nodo da utilizzare, invia il messaggio utilizzando la classe MessageClient.

L'esempio seguente mostra come inviare un messaggio al nodo abilitato alla trascrizione da un dispositivo indossabile. Questa chiamata è sincrona e blocca l'elaborazione finché il sistema mette in coda il messaggio per il recapito.

Nota: un codice risultato riuscito non garantisce la pubblicazione di il messaggio. Se la tua app richiede affidabilità dei dati, valuta la possibilità di utilizzare DataItem oggetti ChannelClient per inviare dati tra dispositivi.

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 saperne di più sulle chiamate asincrone e sincrone a Google Play Services e quando utilizzarli, consulta l'API Tasks.

Puoi anche trasmettere messaggi a tutti i nodi connessi. Per recuperare tutte le 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 notifiche dei messaggi ricevuti, implementa la MessageClient.OnMessageReceivedListener per fornire un listener per gli eventi dei messaggi. Quindi, registra il listener con addListener . L'esempio seguente mostra come implementare il listener per controllare il valore 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. Informazioni su come implementare un servizio o un'attività completi in Monitora gli eventi del livello dati.