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 aplikasi Anda di mana pun di jaringan Wear OS by Google.
Untuk contoh cara bekerja secara efektif dengan Data Layer API, lihat aplikasi Contoh Android DataLayer.
Menunggu status panggilan Data Layer
Panggilan ke Data Layer API—misalnya panggilan yang menggunakan
metode putDataItem
dari
class
DataClient
—terkadang menampilkan
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 asinkron maupun sinkron.
Panggilan asinkron
Jika kode Anda berjalan di UI thread utama, jangan buat panggilan pemblokiran ke
Data Layer API. Jalankan panggilan secara asinkron dengan menambahkan metode callback
ke objek Task
, yang diaktifkan saat 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 menggabungkan eksekusi tugas yang berbeda.
Panggilan tersinkron
Jika kode Anda berjalan pada thread pengendali yang berbeda di layanan latar belakang,
seperti dalam
WearableListenerService
,
tidak masalah jika panggilan memblokirnya. Dalam hal ini, Anda dapat memanggil Tasks.await()
pada objek
Task
yang melakukan pemblokiran hingga permintaan selesai dan menampilkan
objek Result
. Hal ini ditunjukkan dalam contoh berikut.
Catatan: Pastikan Anda tidak memanggilnya saat berada di thread utama.
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, biasanya Anda perlu memproses peristiwa penting seperti item data yang dibuat dan pesan yang diterima.
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: Pertimbangkan penggunaan baterai aplikasi saat memilih
implementasi pemroses. WearableListenerService
terdaftar dalam manifes aplikasi dan dapat meluncurkan aplikasi jika belum
berjalan. Jika Anda hanya perlu memproses peristiwa ketika aplikasi sudah berjalan,
yang biasanya terjadi dengan aplikasi interaktif, jangan gunakan
WearableListenerService
. Namun, daftarkan pemroses langsung.
Misalnya, gunakan metode addListener
dari class
DataClient
. Hal ini dapat mengurangi beban sistem dan menghemat penggunaan baterai.
Menggunakan WearableListenerService
Biasanya, Anda harus membuat instance
WearableListenerService
di aplikasi wearable maupun
perangkat genggam. Namun, jika tidak tertarik dengan peristiwa data dalam salah satu
aplikasi, 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 mengupdate UI-nya. Aplikasi wearable tidak pernah mengupdate 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
adalah sebagai berikut:
-
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.
Anda juga 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" android:exported="true" tools:ignore="ExportedService" > <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, smartwatch 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 jalur literal atau awalan jalur. Untuk melakukannya, Anda harus menetapkan host pengganti atau host tertentu. Jika tidak, sistem akan mengabaikan jalur yang Anda tetapkan.
Untuk mengetahui informasi selengkapnya tentang jenis filter yang didukung Wear OS, lihat
dokumentasi referensi API untuk
WearableListenerService
.
Untuk mengetahui informasi selengkapnya tentang aturan pencocokan dan filter data, lihat dokumentasi
referensi API untuk elemen manifes
<data>
.
Saat mencocokkan filter intent, ingatlah dua aturan penting:
- Jika tidak ada skema yang ditetapkan untuk filter intent, sistem akan mengabaikan semua atribut URI lainnya.
- Jika tidak ada host yang ditetapkan untuk filter, sistem akan mengabaikan semua atribut jalur.
Menggunakan pemroses langsung
Jika aplikasi hanya berfokus 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, lakukan langkah berikut:
- 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 jalur 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
, bergantung 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
Seperti yang telah disebutkan, sama seperti Anda dapat menentukan filter intent untuk
objek WearableListenerService
berbasis manifes, Anda juga dapat menggunakan filter intent saat mendaftarkan pemroses langsung melalui
Wearable
API. Aturan yang sama berlaku untuk pemroses langsung berbasis API maupun
pemroses berbasis manifes.
Pola yang cukup umum adalah mendaftarkan pemroses dengan jalur tertentu atau awalan jalur
dalam metode onResume()
aktivitas, lalu menghapus pemroses dalam
metode onPause()
aktivitas.
Mengimplementasikan pemroses dengan cara ini memungkinkan aplikasi Anda menerima
peristiwa secara lebih selektif sehingga meningkatkan desain dan efisiensinya.