Sie senden Nachrichten mit der
MessageClient
API und hängen die folgenden Elemente an die Nachricht an:
- Eine optionale beliebige Nutzlast
- Ein Pfad, der die Aktion der Nachricht eindeutig identifiziert
Anders als bei Datenelementen erfolgt keine Synchronisierung zwischen den Handheld- und Wearable-Apps. Nachrichten sind ein einseitiger Kommunikationsmechanismus, der für Remoteprozeduraufrufe (RPC) nützlich ist, z. B. das Senden einer Nachricht an das Wearable, um eine Aktivität zu starten.
Mehrere Wearables können mit dem Handheld-Gerät eines Nutzers verbunden werden. Jedes verbundene Gerät im Netzwerk wird als Knoten betrachtet.
Bei mehreren verbundenen Geräten müssen Sie berücksichtigen, welche Knoten die Nachrichten empfangen. Senden Sie beispielsweise in einer Anwendung zur Sprachtranskription, die Sprachdaten auf dem Wearable-Gerät empfängt, an einen Knoten mit entsprechender Prozessor- und Akkukapazität zur Verarbeitung der Anfrage gesendet wird, z. B. an ein Handheld-Gerät.
Hinweis:Wenn Sie die Details Ihrer Nachricht angeben, berücksichtigen Sie die Möglichkeit mehrerer verbundener Knoten. Prüfen Sie, ob die Nachricht an die gewünschten Geräte oder Knoten gesendet wird.
Anwendungsbeispiele finden Sie in den folgenden Beispiel-Apps:
Eine Nachricht posten
Eine Wearable-App kann Nutzern Funktionen wie Sprachtranskription bieten. Nutzer können in das Mikrofon ihres Wearable-Geräts sprechen und ein Transkript in einer Notiz speichern lassen. Da ein Wearable in der Regel nicht die für die Verarbeitung der Sprachtranskription erforderliche Rechenleistung und Akkukapazität hat, muss die Anwendung diese Aufgaben auf ein leistungsfähigeres verbundenes Gerät übertragen.
In den folgenden Abschnitten wird gezeigt, wie Sie Geräteknoten bewerben, die Aktivitätsanfragen verarbeiten, Knoten ermitteln, die einen angeforderten Bedarf erfüllen, und Nachrichten an diese Knoten senden.
Werbefunktionen
Wenn Sie von einem Wearable aus eine Aktivität auf einem Handheld-Gerät starten möchten, verwenden Sie die Klasse
MessageClient
, um die Anfrage zu senden. Da mehrere Wearables mit dem Handheld-Gerät verbunden werden können, muss die Wearable-App feststellen, ob ein verbundener Knoten in der Lage ist, die Aktivität zu starten. Geben Sie in Ihrer Handheld-Anwendung an, dass der Knoten, auf dem sie ausgeführt wird, bestimmte Funktionen bietet.
So bewerben Sie die Funktionen Ihrer Handheld-App:
- Erstellen Sie im Verzeichnis
res/values/
Ihres Projekts eine XML-Konfigurationsdatei und nennen Sie siewear.xml
. - Fügen Sie
wear.xml
eine Ressource mit dem Namenandroid_wear_capabilities
hinzu. - Definieren Sie die vom Gerät bereitgestellten Funktionen.
Hinweis:Funktionen sind benutzerdefinierte Strings, die Sie definieren und innerhalb Ihrer App eindeutig sein müssen.
Das folgende Beispiel zeigt, wie Sie eine Funktion namens voice_transcription
zu wear.xml
hinzufügen:
<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>
Knoten mit den erforderlichen Funktionen abrufen
Zu Beginn können Sie die geeigneten Knoten ermitteln, indem Sie die Methode getCapability
der Klasse
CapabilityClient
aufrufen. Damit Sie diese Methode verwenden können, müssen Ihre Wear OS-App und Ihre Smartphone-App dieselbe App-ID haben. Das folgende Beispiel zeigt, wie Sie die Ergebnisse erreichbarer Knoten mit der Funktion voice_transcription
manuell abrufen können:
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); }
Registrieren Sie eine Instanz eines Listeners, insbesondere eine OnCapabilityChangedListener
eines CapabilityClient
-Objekts, damit kompatible Knoten bei der Verbindung zum Wearable-Gerät erkannt werden. Das folgende Beispiel zeigt, wie Sie den Listener registrieren und ein Ergebnis mit erreichbaren Knoten mit der Funktion voice_transcription
abrufen:
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); }
Nachdem Sie die geeigneten Knoten erkannt haben, legen Sie fest, wohin die Nachricht gesendet werden soll. Wählen Sie einen Knoten in der Nähe Ihres Wearable-Geräts aus, um die Nachrichtenweiterleitung über mehrere Knoten zu minimieren. Ein Knoten in der Nähe ist ein Knoten, der direkt mit dem Gerät verbunden ist. Rufen Sie die Methode
Node.isNearby()
auf, um festzustellen, ob sich ein Knoten in der Nähe befindet, z. B. über Bluetooth. Wenn sich mehr als ein Knoten in der Nähe befindet, wählen Sie einen beliebig aus. Wenn sich kein fähiger Knoten in der Nähe befindet, wählen Sie entsprechend einen geeigneten Knoten aus.
Das folgende Beispiel zeigt, wie Sie den besten zu verwendenden Knoten ermitteln können:
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; }
Die Botschaft übermitteln
Wenn Sie einen zu verwendenden Knoten identifiziert haben, senden Sie die Nachricht mit der Klasse
MessageClient
.
Das folgende Beispiel zeigt, wie Sie von einem Wearable-Gerät eine Nachricht an den transkriptionsfähigen Knoten senden. Dieser Aufruf ist synchron und blockiert die Verarbeitung, bis das System die Nachricht zur Zustellung in die Warteschlange stellt.
Hinweis:Ein erfolgreicher Ergebniscode garantiert nicht, dass die Nachricht zugestellt wird. Wenn deine App Datenzuverlässigkeit erfordert, kannst du
DataItem
-Objekte oder die Klasse ChannelClient
verwenden, um Daten zwischen Geräten zu senden.
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 } }
Hinweis:Weitere Informationen zu asynchronen und synchronen Aufrufen von Google Play-Diensten und ihrer Verwendung finden Sie in der Tasks API.
Sie können auch Nachrichten an alle verbundenen Knoten senden. Implementieren Sie den folgenden Code, um alle verbundenen Knoten abzurufen, an die Sie Nachrichten senden können:
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; }
Nachrichten empfangen
Wenn Sie über empfangene Nachrichten informiert werden möchten, implementieren Sie die
MessageClient.OnMessageReceivedListener
-Schnittstelle, um einen Listener für Nachrichtenereignisse bereitzustellen. Registrieren Sie dann den Listener mit der Methode addListener
. Das folgende Beispiel zeigt, wie Sie den Listener implementieren können, um VOICE_TRANSCRIPTION_MESSAGE_PATH
zu prüfen. Wenn diese Bedingung true
ist, starten Sie eine Aktivität zur Verarbeitung der Sprachdaten.
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); } }
Für diesen Code sind weitere Implementierungsdetails erforderlich. Informationen zum Implementieren eines vollständigen Listener-Dienstes oder einer -Aktivität finden Sie unter Auf Datenschichtereignisse warten.