Wysyłanie i odbieranie wiadomości na Wear

Wysyłasz wiadomości za pomocą MessageClient API i dołącz do wiadomości te elementy:

  • Opcjonalny dowolny ładunek
  • Ścieżka, która jednoznacznie identyfikuje działanie wiadomości

W przeciwieństwie do elementów danych synchronizacja między aplikacje na urządzenia mobilne i urządzenia do noszenia. Komunikaty to jednokierunkowy mechanizm komunikacji przydatny w przypadku zdalnych wywołań procedur (RPC), na przykład wysłanie wiadomości do urządzenia do noszenia w celu rozpoczęcia aktywności.

Do urządzenia mobilnego użytkownika można połączyć wiele urządzeń do noszenia. Każde połączone urządzenie w: sieć jest uznawana za węzeł.

Gdy masz kilka połączonych urządzeń, wybierz że węzły odbierają komunikaty. Na przykład w aplikacji do transkrypcji mowy, która odbiera dane głosowe urządzenia do noszenia, wyślij wiadomość do węzła z mocą obliczeniową i baterią. może obsłużyć żądanie, np. w urządzeniu przenośnym.

Uwaga: Podczas określania szczegółów wiadomości weź pod uwagę możliwość połączonych węzłów. Sprawdź, czy wiadomość jest dostarczana do odpowiednich urządzeń lub węzłów.

Przykłady użycia znajdziesz w tej przykładowej aplikacji: Warstwy danych

Wyślij wiadomość

Aplikacja do noszenia może oferować użytkownikom funkcje takie jak obsługa głosu transkrypcję. Użytkownicy mogą mówić do mikrofonu urządzenia do noszenia i wyświetlać transkrypcję zapisano w notatce. Ponieważ urządzenie do noszenia zwykle nie ma mocy obliczeniowej ani baterii wymagana do obsługi transkrypcji głosu, aplikacja musi przekazać tę pracę i lepsze połączone urządzenie.

Sekcje poniżej pokazują, jak reklamować węzły urządzeń, które mogą przetwarzać aktywność żądań, wykrywa węzły zdolne do zaspokojenia oczekiwanej potrzeby i wysyłają do nich komunikaty węzłów.

Aby uruchomić aktywność na urządzeniu przenośnym z urządzenia do noszenia, użyj MessageClient zajęcia, aby wysłać żądanie. Wiele urządzeń do noszenia można połączyć z na urządzeniu mobilnym, musi ona określić, czy połączony węzeł jest nie może rozpocząć działania. W aplikacji przenośnej umieść informację, że węzeł i zapewniają określone możliwości.

Aby reklamować możliwości aplikacji mobilnej, wykonaj te czynności:

  1. Utwórz plik konfiguracji XML w katalogu res/values/ projektu i nadaj mu nazwę wear.xml.
  2. Dodaj zasób o nazwie android_wear_capabilities do folderu wear.xml.
  3. Określ możliwości zapewniane przez urządzenie.

Uwaga: Możliwości to zdefiniowane przez Ciebie ciągi niestandardowe, które muszą być unikalne w obrębie 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 uprawnieniami

Początkowo możesz wykryć węzły obsługujące tę funkcję, wywołując metodę Metoda funkcji getCapability CapabilityClient zajęcia. Aby korzystać z tej metody, aplikacja na Wear OS i telefon musi mieć ten sam identyfikator aplikacji. Przykład poniżej pokazuje, jak ręcznie pobierać wyniki z osiągalnych węzłów za pomocą Funkcja 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 wykrywać węzły obsługujące tę funkcję podczas łączenia się z urządzeniem do noszenia, zarejestruj wystąpienie odbiornika, a konkretnie OnCapabilityChangedListener obiektu CapabilityClient. Ten przykład pokazuje, jak zarejestrować detektor i pobrać wynik z osiągalnymi węzłami, w których Funkcja 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ę ustal, gdzie wysłać wiadomość. Wybierz węzeł w pobliżu urządzenia do noszenia, by zminimalizować kierowanie wiadomości przez wiele węzłów. Węzeł w pobliżu to taki, który jest bezpośrednio połączony do urządzenia. Aby określić, czy węzeł znajduje się w pobliżu, np. połączony przez Bluetooth, wywołaj Node.isNearby(). Jeśli w pobliżu znajduje się więcej niż 1 węzeł, wybierz jeden według uznania. analogicznie, jeśli w pobliżu nie ma odpowiedniego węzła, wybierz taki węzeł dowolnie.

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;
}

Przekaż wiadomość

Po wybraniu węzła wyślij wiadomość za pomocą klasy MessageClient.

Poniższy przykład pokazuje, jak wysłać wiadomość do węzła z obsługą transkrypcji z urządzenia do noszenia. To wywołanie jest synchroniczne i blokuje przetwarzanie do czasu system umieści wiadomość w kolejce do dostarczenia.

Uwaga: pomyślny kod wyniku nie gwarantuje wyświetlenia wiadomość. Jeśli Twoja aplikacja wymaga niezawodności danych, rozważ użycie DataItem obiekty lub 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 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: aby dowiedzieć się więcej o asynchronicznych i synchronicznych wywołaniach funkcji Informacje o tym, kiedy korzystać z Usług Google Play, znajdziesz w artykule Tasks API.

Możesz też przesyłać komunikaty do wszystkich połączonych węzłów. Aby pobrać wszystkie w połączonych węzłach, 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 MessageClient.OnMessageReceivedListener , aby udostępnić detektor zdarzeń wiadomości. Następnie zarejestruj detektor dzięki funkcji addListener . Przykład poniżej pokazuje, jak możesz wdrożyć detektor, aby sprawdzać 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. Więcej informacji o jak wdrożyć pełną usługę detektora lub działanie w Nasłuch zdarzeń warstwy danych.