Wiadomości wysyłasz za pomocą interfejsu
MessageClient
API, do którego dołączasz te elementy:
- opcjonalny dowolny ładunek,
- Ścieżka, która jednoznacznie identyfikuje działanie wiadomości.
W przeciwieństwie do elementów danych nie ma synchronizacji między aplikacjami na urządzenie przenośne i na urządzenie do noszenia. Wiadomości to jednokierunkowy mechanizm komunikacji przydatny w przypadku zdalnych wywołań procedur (RPC), np. wysyłania wiadomości do urządzenia do noszenia w celu rozpoczęcia aktywności.
Z urządzeniem przenośnym użytkownika można połączyć wiele urządzeń do noszenia. Każde urządzenie połączone z siecią jest uważane za węzeł.
W przypadku wielu połączonych urządzeń musisz określić, które węzły będą odbierać wiadomości. Na przykład w aplikacji do transkrypcji głosu, która odbiera dane głosowe na urządzeniu do noszenia, wyślij wiadomość do węzła o mocy obliczeniowej i pojemności baterii wystarczających do obsługi żądania, np. do urządzenia przenośnego.
Uwaga: podając szczegóły wiadomości, weź pod uwagę możliwość połączenia wielu węzłów. Upewnij się, że wiadomość jest dostarczana na odpowiednie urządzenia lub węzły.
Przykłady użycia znajdziesz w tej przykładowej aplikacji: DataLayer
Wyślij wiadomość
Aplikacja na urządzenie do noszenia może udostępniać użytkownikom funkcje, takie jak transkrypcja głosu. Użytkownicy mogą mówić do mikrofonu urządzenia do noszenia, a transkrypcja zostanie zapisana w notatce. Urządzenie do noszenia zwykle nie ma mocy obliczeniowej ani pojemności baterii wymaganych do obsługi transkrypcji głosu, więc aplikacja musi przekazać to zadanie do bardziej wydajnego połączonego urządzenia.
W sekcjach poniżej dowiesz się, jak reklamować węzły urządzeń, które mogą przetwarzać żądania aktywności, wykrywać węzły zdolne do zaspokojenia żądanej potrzeby i wysyłać do nich wiadomości.
Możliwości reklamowe
Aby uruchomić aktywność na urządzeniu przenośnym z poziomu urządzenia do noszenia, użyj klasy
MessageClient
do wysłania żądania. Ponieważ z urządzeniem przenośnym można połączyć wiele urządzeń do noszenia, aplikacja na urządzenie do noszenia musi określić, czy połączony węzeł może uruchomić aktywność. W aplikacji na urządzenie przenośne reklamuj, że węzeł, na którym działa aplikacja, ma określone możliwości.
Aby reklamować funkcje aplikacji na urządzenia przenośne:
- Utwórz plik konfiguracji XML w katalogu
res/values/
projektu i nadaj mu nazwęwear.xml
. - Dodaj zasób o nazwie
android_wear_capabilities
dowear.xml
. - Określ funkcje, które zapewnia urządzenie.
Uwaga: możliwości to ciągi znaków zdefiniowane przez Ciebie, które muszą być unikalne w aplikacji.
Poniższy przykład pokazuje, jak dodać do wear.xml
funkcję o nazwie voice_transcription
:
<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>
Pobieranie węzłów o wymaganych możliwościach
Początkowo możesz wykryć obsługiwane węzły, wywołując metodę getCapability
klasy
CapabilityClient
. Aby użyć tej metody, aplikacja na Wear OS i aplikacja na telefon muszą mieć ten sam identyfikator aplikacji. W przykładzie poniżej pokazujemy, jak ręcznie pobrać wyniki dotyczące osiągalnych węzłów za pomocą funkcji 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); }
Ostrzeżenie:
zanim użyjesz interfejsu Wearable Data Layer API, sprawdź, czy jest on dostępny na urządzeniu. W przeciwnym razie wystąpi wyjątek. Użyj klasy GoogleApiAvailability
, tak jak w przypadku klasy Horologist.
Aby wykrywać węzły, które mogą się łączyć z urządzeniem do noszenia, zarejestruj instancję odbiornika, a konkretnie OnCapabilityChangedListener
CapabilityClient
. Przykład poniżej pokazuje, jak zarejestrować odbiornik i pobrać wynik z dostępnymi węzłami, które mają funkcję 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); }
Po wykryciu odpowiednich węzłów określ, gdzie wysłać wiadomość. Wybierz węzeł, który znajduje się w pobliżu urządzenia do noszenia, aby zminimalizować routing wiadomości przez wiele węzłów. Węzeł w pobliżu to węzeł bezpośrednio połączony z urządzeniem. Aby sprawdzić, czy węzeł znajduje się w pobliżu, np. jest połączony przez Bluetooth, wywołaj metodę
Node.isNearby()
. Jeśli w pobliżu znajduje się więcej niż 1 węzeł, wybierz dowolny z nich. Podobnie, jeśli w pobliżu nie ma odpowiedniego węzła, wybierz dowolny odpowiedni węzeł.
Poniższy przykład pokazuje, jak określić najlepszy węzeł do użycia:
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; }
Przekaż wiadomość
Po wybraniu węzła, którego chcesz użyć, wyślij wiadomość za pomocą klasy
MessageClient
.
Poniższy przykład pokazuje, jak wysłać wiadomość do węzła z funkcją transkrypcji z urządzenia do noszenia. To wywołanie jest synchroniczne i blokuje przetwarzanie do momentu, gdy system umieści wiadomość w kolejce do dostarczenia.
Uwaga: kod wyniku oznaczający powodzenie nie gwarantuje dostarczenia wiadomości. Jeśli Twoja aplikacja wymaga niezawodności danych, rozważ użycie obiektów
DataItem
lub klasy ChannelClient
do przesyłania danych między urządzeniami.
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 } }
Uwaga: więcej informacji o wywołaniach asynchronicznych i synchronicznych Usług Google Play oraz o tym, kiedy ich używać, znajdziesz w interfejsie API zadań.
Możesz też przesyłać wiadomości do wszystkich połączonych węzłów. Aby pobrać wszystkie połączone węzły, do których możesz wysyłać wiadomości, zaimplementuj ten kod:
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; }
Odbieranie wiadomości
Aby otrzymywać powiadomienia o odebranych wiadomościach, zaimplementuj interfejs
MessageClient.OnMessageReceivedListener
w celu udostępnienia detektora zdarzeń związanych z wiadomościami. Następnie zarejestruj odbiorcę za pomocą metody addListener
. Poniższy przykład pokazuje, jak możesz zaimplementować odbiornik, aby sprawdzić VOICE_TRANSCRIPTION_MESSAGE_PATH
. Jeśli ten warunek jest true
, rozpocznij aktywność, aby przetworzyć dane głosowe.
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); } }
Ten kod wymaga więcej szczegółów implementacji. Dowiedz się, jak wdrożyć pełną usługę lub aktywność odbiornika w artykule Wykrywanie zdarzeń warstwy danych.