Mengirim dan menerima pesan di Wear

Untuk mengirim pesan, gunakan API MessageClient dan lampirkan item berikut ke pesan:

  • Payload acak opsional
  • Jalur yang mengidentifikasi tindakan pesan secara unik

Tidak seperti item data, tidak ada sinkronisasi antara aplikasi di perangkat genggam dan perangkat wearable. Pesan adalah mekanisme komunikasi satu arah yang berguna untuk remote procedure call (RPC), seperti pengiriman pesan ke perangkat wearable untuk memulai aktivitas.

Beberapa perangkat wearable dapat dihubungkan ke perangkat genggam pengguna. Setiap perangkat yang terhubung di jaringan tersebut akan dianggap sebagai node.

Dengan beberapa perangkat yang terhubung, Anda harus mempertimbangkan node mana yang menerima pesan. Misalnya, dalam aplikasi transkripsi suara yang menerima data suara pada perangkat wearable, kirim pesan ke node dengan kapasitas baterai dan daya pemrosesan untuk menangani permintaan, seperti perangkat genggam.

Catatan: Saat Anda menentukan detail pesan, pertimbangkan kemungkinan beberapa node yang terhubung. Pastikan pesan dikirim ke perangkat atau node yang diinginkan.

Lihat aplikasi contoh berikut untuk contoh penggunaan: Lapisan Data

Mengirim pesan

Aplikasi wearable dapat memberikan fungsi bagi pengguna, misalnya transkripsi suara. Pengguna dapat berbicara melalui mikrofon perangkat wearable dan menyimpan transkrip ke catatan. Karena perangkat wearable biasanya tidak memiliki kapasitas baterai dan daya pemrosesan yang diperlukan untuk menangani aktivitas transkripsi suara, aplikasi tersebut harus melimpahkan tugas ini ke perangkat terhubung yang lebih mampu melakukannya.

Bagian berikut menunjukkan cara memberi tahu node perangkat yang dapat memproses permintaan aktivitas, menemukan node yang mampu memenuhi kebutuhan yang diminta, dan mengirim pesan ke node tersebut.

Untuk meluncurkan aktivitas pada perangkat genggam dari perangkat wearable, gunakan class MessageClient untuk mengirim permintaan. Karena sebuah perangkat genggam dapat terhubung ke lebih dari satu perangkat wearable sekaligus, aplikasi wearable perlu memastikan bahwa node yang terhubung mampu meluncurkan aktivitas. Di aplikasi genggam Anda, beri tahukan bahwa node yang dijalankan memberikan kemampuan spesifik.

Untuk memberitahukan kemampuan aplikasi perangkat genggam Anda, lakukan hal berikut:

  1. Buat file konfigurasi XML di direktori res/values/ project Anda dan berikan nama wear.xml.
  2. Tambahkan resource bernama android_wear_capabilities ke wear.xml.
  3. Tentukan kemampuan yang disediakan perangkat tersebut.

Catatan: Kemampuan adalah string kustom yang Anda tetapkan dan harus unik dalam aplikasi.

Contoh berikut menunjukkan cara menambahkan kemampuan bernama voice_transcription ke 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>

Mengambil node dengan kemampuan yang diperlukan

Pada awalnya, Anda dapat mendeteksi node yang kompeten dengan memanggil metode getCapability dari class CapabilityClient. Untuk menggunakan metode ini, aplikasi Wear OS dan aplikasi ponsel Anda harus memiliki ID aplikasi yang sama. Contoh berikut menunjukkan cara mengambil hasil dari node yang dapat dijangkau secara manual dengan kemampuan 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);
}

Untuk mendeteksi node yang kompeten saat terhubung ke perangkat wearable, daftarkan instance pemroses, khususnya OnCapabilityChangedListener dari objek CapabilityClient. Contoh berikut menunjukkan cara mendaftarkan pemroses dan mengambil hasil dengan node yang dapat dijangkau dan memiliki kemampuan 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);
}

Setelah mendeteksi node yang kompeten, tentukan tujuan pengiriman pesan. Pilih node yang berada di dekat perangkat wearable Anda untuk meminimalkan {i>routing<i} pesan melalui beberapa {i>node<i}. {i>Node<i} yang berdekatan didefinisikan sebagai {i>node<i} yang terhubung langsung ke perangkat. Untuk menentukan apakah node berada di sekitar seperti terhubung melalui Bluetooth, panggil metode Node.isNearby(). Jika ada lebih dari satu node di sekitar, pilih satu secara acak. Demikian juga, jika tidak ada node yang kompeten di sekitar, pilih satu node yang kompeten secara acak.

Contoh berikut menunjukkan cara yang mungkin dilakukan dalam menentukan node terbaik untuk digunakan:

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

Mengirim pesan

Setelah Anda mengidentifikasi node yang akan digunakan, kirim pesan menggunakan class MessageClient.

Contoh berikut menunjukkan cara mengirim pesan ke node yang mampu mentranskripsi dari perangkat wearable. Panggilan ini sinkron dan memblokir pemrosesan hingga sistem mengantrekan pesan untuk dikirim.

Catatan: Kode hasil yang sukses tidak menjamin pengiriman pesan. Jika aplikasi Anda memerlukan keandalan data, pertimbangkan untuk menggunakan objek DataItem atau class ChannelClient dalam mengirim data antar-perangkat.

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

Catatan: Untuk mempelajari lebih lanjut panggilan asinkron dan sinkron ke layanan Google Play dan waktu penggunaannya, lihat Tasks API.

Anda juga dapat menyiarkan pesan ke semua node yang terhubung. Untuk mengambil semua node terhubung yang dapat Anda kirimi pesan, terapkan kode berikut:

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

Menerima pesan

Agar mendapatkan notifikasi saat menerima pesan, terapkan antarmuka MessageClient.OnMessageReceivedListener sebagai pemroses untuk peristiwa pesan. Kemudian, daftarkan pemroses dengan metode addListener. Contoh berikut menunjukkan cara menerapkan pemroses untuk memeriksa VOICE_TRANSCRIPTION_MESSAGE_PATH. Jika kondisi ini berupa true, mulailah aktivitas untuk memproses data suara.

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

Kode ini memerlukan detail penerapan selengkapnya. Pelajari cara menerapkan layanan atau aktivitas pemroses yang lengkap di Memproses peristiwa lapisan data.