Ketika melakukan panggilan ke Data Layer API, Anda bisa mendapatkan status panggilan tersebut ketika sudah selesai. Anda juga dapat memproses peristiwa data yang dihasilkan dari perubahan data yang dilakukan oleh aplikasi Anda di mana pun pada jaringan Wear OS by Google.
Catatan: Aplikasi Wear dapat berkomunikasi dengan aplikasi ponsel menggunakan Data Layer API, tetapi menghubungkan ke jaringan menggunakan API ini tidak disarankan.
Lihat referensi terkait berikut:
Menunggu status panggilan Lapisan Data
Panggilan ke Data Layer API, misalnya panggilan yang menggunakan metode putDataItem
dari class
DataClient
, terkadang mengembalikan objek
Task<ResultType>
. Segera setelah objek Task
dibuat, operasi akan dimasukkan ke antrean di latar belakang. Jika Anda tidak melakukan apa pun setelah ini, operasi
akan diselesaikan tanpa pemberitahuan. Namun, setelah operasi ini selesai, biasanya ada hal yang ingin Anda lakukan dengan hasilnya sehingga objek Task
akan membiarkan Anda menunggu status hasilnya, baik secara sinkron maupun asinkron.
Panggilan asinkron
Jika kode Anda berjalan di UI thread utama, jangan buat panggilan pemblokiran ke Data Layer API. Anda dapat menjalankan panggilan secara asinkron dengan menambahkan metode callback ke objek Task
, yang akan diaktifkan ketika operasi selesai:
Kotlin
// Using Kotlin function references task.addOnSuccessListener(::handleDataItem) task.addOnFailureListener(::handleDataItemError) task.addOnCompleteListener(::handleTaskComplete) ... fun handleDataItem(dataItem: DataItem) { ... } fun handleDataItemError(exception: Exception) { ... } fun handleTaskComplete(task: Task<DataItem>) { ... }
Java
// Using Java 8 Lambdas. task.addOnSuccessListener(dataItem -> handleDataItem(dataItem)); task.addOnFailureListener(exception -> handleDataItemError(exception)); task.addOnCompleteListener(task -> handleTaskComplete(task));
Lihat Task API untuk kemungkinan lainnya, termasuk kemampuan untuk menggabungkan eksekusi beberapa tugas secara bersamaan.
Panggilan tersinkron
Jika kode Anda berjalan pada thread pengendali yang berbeda di layanan latar belakang (misalnya yang terjadi di
WearableListenerService
), tidak masalah jika panggilan memblokirnya. Dalam hal ini, Anda dapat memanggil Tasks.await() pada objek Task
, yang melakukan pemblokiran hingga permintaan selesai dan mengembalikan objek Result
:
Kotlin
try { Tasks.await(dataItemTask).apply { Log.d(TAG, "Data item set: $uri") } } catch (e: ExecutionException) { ... } catch (e: InterruptedException) { ... }
Java
try { DataItem item = Tasks.await(dataItemTask); Log.d(TAG, "Data item set: " + item.getUri()); } catch (ExecutionException | InterruptedException e) { ... }
Memproses peristiwa Lapisan Data
Karena lapisan data menyinkronkan dan mengirimkan data ke perangkat genggam dan wearable, Anda biasanya perlu memproses peristiwa penting. Contoh peristiwa seperti ini mencakup pembuatan item data dan penerimaan pesan.
Untuk memproses peristiwa lapisan data, Anda memiliki dua opsi:
- Buat layanan yang memperluas
WearableListenerService
. - Buat aktivitas atau class yang mengimplementasikan antarmuka
DataClient.OnDataChangedListener
.
Dengan kedua opsi ini, Anda akan menggantikan metode callback peristiwa data untuk peristiwa yang ingin ditangani.
Catatan: Terkait penggunaan baterai,
WearableListenerService
terdaftar sebagai manifes aplikasi dan dapat meluncurkan aplikasi jika belum berjalan. Jika hanya perlu memproses peristiwa ketika aplikasi sudah berjalan, yang biasanya terjadi dengan aplikasi interaktif, jangan gunakan WearableListenerService
. Namun, sebagai contoh, daftarkan pemroses langsung menggunakan metode addListener
dari class DataClient
. Hal ini dapat mengurangi beban sistem dan menghemat penggunaan baterai.
Dengan WearableListenerService
Biasanya, Anda akan membuat instance layanan ini baik dalam aplikasi wearable maupun perangkat genggam. Jika tidak tertarik dengan peristiwa data dalam salah satu aplikasi ini, Anda tidak perlu mengimplementasikan layanan dalam aplikasi tersebut.
Misalnya, Anda boleh memiliki aplikasi perangkat genggam yang menetapkan dan mendapatkan objek item data serta aplikasi wearable yang memproses update ini untuk memperbarui UI-nya. Perangkat wearable tidak pernah memperbarui item data apa pun sehingga aplikasi perangkat genggam tidak memproses peristiwa data apa pun dari aplikasi wearable.
Beberapa peristiwa yang dapat Anda proses menggunakan WearableListenerService
di antaranya adalah:
onDataChanged()
: Setiap kali objek item data dibuat, dihapus, atau diubah, sistem akan memicu callback ini pada semua node yang terhubung.onMessageReceived()
: Pesan yang dikirim dari node akan memicu callback ini pada node target.onCapabilityChanged()
: Ketika kemampuan yang disebutkan oleh instance aplikasi Anda tersedia di jaringan, peristiwa tersebut akan memicu callback ini. Jika sedang mencari node terdekat, Anda dapat meminta metodeisNearby()
dari node yang disediakan dalam callback.
Selain yang ada dalam daftar ini, Anda dapat memproses peristiwa dari
ChannelClient.ChannelCallback
, seperti onChannelOpened()
.
Semua peristiwa di atas dijalankan di thread latar belakang, bukan di thread utama.
Untuk membuat WearableListenerService
, ikuti langkah-langkah berikut:
- Buat class yang memperluas
WearableListenerService
. - Proses peristiwa yang menarik bagi Anda, seperti
onDataChanged()
. - Deklarasikan filter intent dalam manifes Android untuk memberi tahu sistem tentang
WearableListenerService
Anda. Deklarasi ini memungkinkan sistem mengikat layanan sesuai kebutuhan.
Contoh berikut ini menunjukkan cara mengimplementasikan WearableListenerService
sederhana:
Kotlin
private const val TAG = "DataLayerSample" private const val START_ACTIVITY_PATH = "/start-activity" private const val DATA_ITEM_RECEIVED_PATH = "/data-item-received" class DataLayerListenerService : WearableListenerService() { override fun onDataChanged(dataEvents: DataEventBuffer) { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "onDataChanged: $dataEvents") } // Loop through the events and send a message // to the node that created the data item. dataEvents.map { it.dataItem.uri } .forEach { uri -> // Get the node id from the host value of the URI val nodeId: String = uri.host // Set the data of the message to be the bytes of the URI val payload: ByteArray = uri.toString().toByteArray() // Send the RPC Wearable.getMessageClient(this) .sendMessage(nodeId, DATA_ITEM_RECEIVED_PATH, payload) } } }
Java
public class DataLayerListenerService extends WearableListenerService { private static final String TAG = "DataLayerSample"; private static final String START_ACTIVITY_PATH = "/start-activity"; private static final String DATA_ITEM_RECEIVED_PATH = "/data-item-received"; @Override public void onDataChanged(DataEventBuffer dataEvents) { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "onDataChanged: " + dataEvents); } // Loop through the events and send a message // to the node that created the data item. for (DataEvent event : dataEvents) { Uri uri = event.getDataItem().getUri(); // Get the node id from the host value of the URI String nodeId = uri.getHost(); // Set the data of the message to be the bytes of the URI byte[] payload = uri.toString().getBytes(); // Send the RPC Wearable.getMessageClient(this).sendMessage( nodeId, DATA_ITEM_RECEIVED_PATH, payload); } } }
Bagian berikutnya menjelaskan cara menggunakan filter intent dengan pemroses ini.
Menggunakan filter dengan WearableListenerService
Filter intent untuk contoh WearableListenerService
yang ditampilkan di bagian sebelumnya mungkin terlihat seperti ini:
<service android:name=".DataLayerListenerService"> <intent-filter> <action android:name="com.google.android.gms.wearable.DATA_CHANGED" /> <data android:scheme="wear" android:host="*" android:path="/start-activity" /> </intent-filter> </service>
Dalam filter ini, tindakan DATA_CHANGED
menggantikan tindakan BIND_LISTENER
yang sebelumnya direkomendasikan sehingga hanya peristiwa tertentu yang akan mengaktifkan atau meluncurkan aplikasi Anda. Perubahan ini meningkatkan efisiensi sistem dan menghemat penggunaan baterai serta overhead lainnya terkait aplikasi Anda. Dalam contoh ini, jam tangan memproses item data /start-activity
, dan ponsel memproses respons pesan /data-item-received
.
Aturan pencocokan filter Android standar berlaku. Anda dapat menetapkan beberapa layanan
per manifes, beberapa filter intent per layanan, beberapa tindakan per filter, dan
beberapa stanza data per filter. Filter dapat mencocokkan host pengganti
atau host tertentu. Untuk mencocokkan host pengganti, gunakan host="*"
. Untuk mencocokkan host tertentu, tetapkan host=<node_id>
.
Anda juga dapat mencocokkan lokasi literal atau awalan lokasi. Jika melakukan pencocokan menurut lokasi atau awalan lokasi, Anda harus menetapkan host pengganti atau host tertentu. Jika tidak, sistem akan mengabaikan lokasi yang ditetapkan.
Untuk mengetahui informasi selengkapnya tentang jenis filter yang didukung Wear, lihat dokumentasi referensi API untuk WearableListenerService
.
Untuk mengetahui informasi selengkapnya tentang aturan pencocokan dan filter data, lihat dokumentasi referensi API untuk elemen manifes data
.
Ketika mencocokkan filter intent, ada dua aturan penting yang harus diingat:
- Jika suatu skema tidak ditetapkan untuk filter intent, sistem akan mengabaikan semua atribut URI lainnya.
- Jika tidak ada host yang ditetapkan untuk filter, sistem akan mengabaikan semua atribut lokasi.
Dengan pemroses langsung
Jika aplikasi hanya fokus pada peristiwa lapisan data ketika pengguna berinteraksi dengan aplikasi, layanan berdurasi panjang mungkin tidak diperlukan untuk menangani setiap perubahan data. Dalam hal ini, Anda dapat memproses peristiwa dalam aktivitas dengan mengimplementasikan satu atau beberapa antarmuka berikut:
DataClient.OnDataChangedListener
MessageClient.OnMessageReceivedListener
CapabilityClient.OnCapabilityChangedListener
ChannelClient.ChannelCallback
Untuk membuat aktivitas yang memproses peristiwa data:
- Implementasikan antarmuka yang diinginkan.
- Di metode
onCreate()
atauonResume()
, panggilWearable.getDataClient(this).addListener()
,MessageClient.addListener()
,CapabilityClient.addListener()
, atauChannelClient.registerChannelCallback()
untuk memberi tahu layanan Google Play bahwa aktivitas Anda tertarik untuk memproses peristiwa lapisan data. - Di
onStop()
atauonPause()
, batalkan pendaftaran semua pemroses denganDataClient.removeListener()
,MessageClient.removeListener()
,CapabilityClient.removeListener()
, atauChannelClient.unregisterChannelCallback()
. - Jika suatu aktivitas hanya tertarik pada peristiwa yang memiliki awalan lokasi tertentu, Anda dapat menambahkan pemroses dengan filter awalan yang sesuai agar hanya menerima data yang relevan dengan status aplikasi saat ini.
- Implementasikan
onDataChanged()
,onMessageReceived()
,onCapabilityChanged()
, atau metode dariChannelClient.ChannelCallback
, tergantung pada antarmuka yang Anda implementasikan. Metode ini dipanggil pada thread utama, atau Anda dapat menentukanLooper
kustom menggunakanWearableOptions
.
Berikut adalah contoh yang mengimplementasikan DataClient.OnDataChangedListener
.
Kotlin
class MainActivity : Activity(), DataClient.OnDataChangedListener { public override fun onResume() { Wearable.getDataClient(this).addListener(this) } override fun onPause() { Wearable.getDataClient(this).removeListener(this) } override fun onDataChanged(dataEvents: DataEventBuffer) { dataEvents.forEach { event -> if (event.type == DataEvent.TYPE_DELETED) { Log.d(TAG, "DataItem deleted: " + event.dataItem.uri) } else if (event.type == DataEvent.TYPE_CHANGED) { Log.d(TAG, "DataItem changed: " + event.dataItem.uri) } } } }
Java
public class MainActivity extends Activity implements DataClient.OnDataChangedListener { @Override public void onResume() { Wearable.getDataClient(this).addListener(this); } @Override protected void onPause() { Wearable.getDataClient(this).removeListener(this); } @Override public void onDataChanged(DataEventBuffer dataEvents) { for (DataEvent event : dataEvents) { if (event.getType() == DataEvent.TYPE_DELETED) { Log.d(TAG, "DataItem deleted: " + event.getDataItem().getUri()); } else if (event.getType() == DataEvent.TYPE_CHANGED) { Log.d(TAG, "DataItem changed: " + event.getDataItem().getUri()); } } } }
Menggunakan filter dengan pemroses langsung
Sesuai yang telah dijelaskan sebelumnya, seperti menetapkan filter intent untuk objek WearableListenerService
berbasis manifes, Anda juga dapat menggunakan filter intent saat mendaftarkan pemroses langsung melalui Wearable API. Aturan yang sama berlaku bagi pemroses langsung berbasis API dan pemroses berbasis manifes.
Pola yang cukup umum adalah mendaftarkan pemroses dengan jalur atau awalan jalur tertentu dalam metode onResume()
aktivitas, dan menghapus pemroses dalam metode onPause()
aktivitas.
Mengimplementasikan pemroses dengan cara ini memungkinkan aplikasi Anda menerima peristiwa secara lebih selektif sehingga meningkatkan desain dan efisiensinya.