Wysyłasz wiadomości za pomocą interfejsu API
MessageClient
i dołączasz do nich te elementy:
- Opcjonalny ładunek dowolny
- Ścieżka jednoznacznie identyfikująca działanie wiadomości
W przeciwieństwie do elementów danych synchronizacja między aplikacjami na komputerze i urządzeniach do noszenia nie jest synchronizowana. Komunikaty to jednokierunkowy mechanizm komunikacji przydatny w przypadku zdalnych wywołań procedur (RPC), na przykład wysyłanie wiadomości do urządzenia do noszenia, aby rozpocząć działanie.
Do urządzenia mobilnego użytkownika można podłączyć wiele urządzeń do noszenia. Każde połączone urządzenie w sieci jest uważane za węzeł.
W przypadku wielu połączonych urządzeń musisz zdecydować, które węzły otrzymają wiadomości. Na przykład w aplikacji transkrypcji głosowej, która odbiera dane głosowe na urządzeniu do noszenia, wyślij wiadomość do węzła o mocy obliczeniowej i mocy baterii do obsługi żądania (np. do urządzenia mobilnego).
Uwaga: określając szczegóły wiadomości, weź pod uwagę możliwość połączenia wielu węzłów. Sprawdź, czy wiadomość została dostarczona do właściwych urządzeń lub węzłów.
Przykłady użycia znajdziesz poniżej.
Wysyłanie wiadomości
Aplikacja 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 i zapisywać transkrypcję w notatce. Urządzenia do noszenia zwykle nie mają mocy obliczeniowej ani pojemności baterii, które są wymagane do obsługi transkrypcji głosowej, więc aplikacja musi przenieść te zadania na bardziej wydajne połączone urządzenie.
Z kolejnych sekcji dowiesz się, jak reklamować węzły urządzeń, które mogą przetwarzać żądania dotyczące aktywności, wykrywać węzły spełniające zamierzone potrzeby i wysyłać do nich komunikaty.
Możliwości reklamowania
Aby uruchomić aktywność na urządzeniu mobilnym z poziomu urządzenia do noszenia, wyślij żądanie za pomocą klasy
MessageClient
. Ponieważ z urządzeniem mobilnym można podłączyć wiele urządzeń do noszenia, aplikacja do noszenia musi określić, czy połączony węzeł może uruchomić aktywność. W aplikacji mobilnej zamieść informację, że węzeł, w którym działa, ma określone możliwości.
Aby reklamować możliwości swojej aplikacji mobilnej:
- W katalogu
res/values/
swojego projektu utwórz plik konfiguracji XML i nazwij gowear.xml
. - Dodaj zasób o nazwie
android_wear_capabilities
do projektuwear.xml
. - Określ funkcje urządzenia.
Uwaga: Możliwości to zdefiniowane przez Ciebie ciągi niestandardowe, które muszą być unikalne w aplikacji.
Poniższy przykład pokazuje, jak dodać możliwość o nazwie voice_transcription
do 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>
Pobieranie węzłów z wymaganymi funkcjami
Początkowo możesz wykryć węzły, które spełniają wymagania, wywołując metodę getCapability
klasy
CapabilityClient
. Aby można było użyć tej metody, aplikacje na Wear OS i telefon muszą mieć ten sam identyfikator aplikacji. Z przykładu poniżej dowiesz się, jak ręcznie pobierać wyniki 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); }
Aby wykryć odpowiednie węzły, gdy łączą się z urządzeniem do noszenia, zarejestruj wystąpienie odbiornika, a w szczególności OnCapabilityChangedListener
obiektu CapabilityClient
. Poniższy przykład pokazuje, jak zarejestrować detektor i pobrać wynik z osiągalnymi węzłami, które obsługują 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 węzłów obsługujących tę funkcję określ, dokąd należy wysłać wiadomość. Wybierz węzeł, który znajduje się blisko urządzenia do noszenia, aby zminimalizować kierowanie wiadomości przez wiele węzłów. Pobliski węzeł to taki,
który jest bezpośrednio połączony z urządzeniem. Aby sprawdzić, czy węzeł znajduje się w pobliżu, na przykład połączony przez Bluetooth, wywołaj metodę
Node.isNearby()
. Jeśli w pobliżu znajduje się więcej niż 1 węzeł, wybierz jeden z nich. Podobnie, jeśli w pobliżu nie ma żadnego odpowiedniego węzła, wybierz ten, który spełnia wymagania.
Z przykładu poniżej dowiesz się, jak wybrać 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; }
Dostarczenie wiadomości
Po wybraniu węzła do użycia wyślij wiadomość za pomocą klasy
MessageClient
.
Poniższy przykład pokazuje, jak wysłać wiadomość z urządzenia do noszenia do węzła obsługującego transkrypcję. To wywołanie jest synchroniczne i blokuje przetwarzanie, dopóki system nie umieści wiadomości w kolejce do dostarczenia.
Uwaga: poprawny kod wyniku nie gwarantuje dostarczenia wiadomości. Jeśli aplikacja wymaga niezawodności danych, rozważ przesyłanie danych między urządzeniami za pomocą obiektów
DataItem
lub klasy ChannelClient
.
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 } }
Uwaga: więcej informacji o asynchronicznych i synchronicznych wywołaniach Usług Google Play oraz o tym, kiedy ich używać, znajdziesz w artykule Tasks API.
Możesz też rozgłaszać komunikaty 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 otrzymanych wiadomościach, zaimplementuj interfejs
MessageClient.OnMessageReceivedListener
z odbiornikiem zdarzeń wiadomości. Następnie zarejestruj odbiornik za pomocą metody addListener
. Ten przykład pokazuje, jak można zaimplementować odbiornik, aby sprawdzić VOICE_TRANSCRIPTION_MESSAGE_PATH
. Jeśli ten warunek to 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. Informacje o tym, jak wdrożyć działanie lub usługę detektora pełnej usługi detektora, znajdziesz w sekcji Nasłuchiwanie zdarzeń warstwy danych.