Dokumen ini menjelaskan cara menyinkronkan data antara perangkat Wear OS dan perangkat genggam.
Mengirim dan menyinkronkan data langsung dari jaringan
Build aplikasi Wear OS untuk berkomunikasi langsung dengan jaringan. Gunakan API yang sama dengan yang Anda gunakan untuk pengembangan seluler, tetapi perhatikan beberapa perbedaan khusus Wear OS.
Menyinkronkan data menggunakan Wear OS Data Layer API
DataClient
mengekspos API agar komponen dapat membaca atau menulis ke DataItem
atau
Asset
.
Anda dapat menetapkan item dan aset data tanpa terhubung ke perangkat apa pun. Keduanya disinkronkan saat perangkat membuat koneksi jaringan. Data ini bersifat pribadi untuk aplikasi Anda dan hanya dapat diakses oleh aplikasi Anda di perangkat lain.
DataItem
disinkronkan di semua perangkat dalam jaringan Wear OS. Item data tersebut biasanya berukuran kecil.Gunakan
Asset
untuk mentransfer objek yang lebih besar, seperti gambar. Sistem melacak aset mana yang telah ditransfer dan melakukan penghapusan duplikat secara otomatis.
Memproses peristiwa di layanan
Perluas class WearableListenerService
. Sistem akan mengelola
siklus proses WearableListenerService
dasar, melakukan binding ke layanan saat
perlu mengirim item data atau pesan dan membatalkan layanan saat tidak
diperlukan.
Memproses peristiwa dalam aktivitas
Terapkan antarmuka OnDataChangedListener
. Gunakan antarmuka ini, bukan
WearableListenerService
, jika Anda ingin memproses perubahan hanya saat
pengguna aktif menggunakan aplikasi Anda.
Mentransfer data
Untuk mengirim objek besar biner melalui transportasi Bluetooth, seperti rekaman suara
dari perangkat lain, Anda dapat melampirkan
Asset
ke item data, lalu menempatkan item data ke dalam datastore replika.
Aset secara otomatis menangani caching data untuk mencegah transmisi ulang dan menghemat bandwidth Bluetooth. Pola umum ditujukan bagi aplikasi perangkat genggam untuk mendownload gambar, memperkecil ke ukuran yang sesuai untuk tampilan di perangkat wearable, dan mentransmisikan ke perangkat wearable sebagai aset. Contoh berikut mendemonstrasikan pola tersebut.
Catatan: Meskipun secara teoritis ukuran item data dibatasi hingga 100 KB, pada praktiknya, item data yang lebih besar dapat digunakan. Untuk item data yang lebih besar, pisahkan data berdasarkan jalur unik dan hindari penggunaan satu jalur untuk semua data. Mentransfer aset besar akan memengaruhi pengalaman pengguna dalam banyak kasus. Jadi, uji aplikasi Anda untuk membantu memastikan aplikasi dapat berperforma baik saat mentransfer aset besar.
Mentransfer aset
Buat aset menggunakan salah satu metode create...()
dalam
class
Asset
.
Konversi bitmap ke aliran byte, lalu panggil
createFromBytes()
untuk membuat aset, seperti ditunjukkan pada contoh berikut.
private fun createAssetFromBitmap(bitmap: Bitmap): Asset = ByteArrayOutputStream().let { byteStream -> bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream) Asset.createFromBytes(byteStream.toByteArray()) }
private static Asset createAssetFromBitmap(Bitmap bitmap) { final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream); return Asset.createFromBytes(byteStream.toByteArray()); }
Selanjutnya, lampirkan aset ke item data dengan metode putAsset()
di
DataMap
atau
PutDataRequest
. Kemudian, masukkan item data ke dalam datastore menggunakan metode
putDataItem()
, seperti ditunjukkan dalam contoh berikut.
Contoh berikut menggunakan PutDataRequest
:
val asset: Asset = BitmapFactory.decodeResource(resources, R.drawable.image).let { bitmap -> createAssetFromBitmap(bitmap) } val request: PutDataRequest = PutDataRequest.create("/image").apply { putAsset("profileImage", asset) } val putTask: Task<DataItem> = Wearable.getDataClient(context).putDataItem(request)
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image); Asset asset = createAssetFromBitmap(bitmap); PutDataRequest request = PutDataRequest.create("/image"); request.putAsset("profileImage", asset); Task<DataItem> putTask = Wearable.getDataClient(context).putDataItem(request);
Contoh berikut menggunakan PutDataMapRequest
:
val asset: Asset = BitmapFactory.decodeResource(resources, R.drawable.image).let { bitmap -> createAssetFromBitmap(bitmap) } val request: PutDataRequest = PutDataMapRequest.create("/image").run { dataMap.putAsset("profileImage", asset) asPutDataRequest() } val putTask: Task<DataItem> = Wearable.getDataClient(context).putDataItem(request)
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image); Asset asset = createAssetFromBitmap(bitmap); PutDataMapRequest dataMap = PutDataMapRequest.create("/image"); dataMap.getDataMap().putAsset("profileImage", asset); PutDataRequest request = dataMap.asPutDataRequest(); Task<DataItem> putTask = Wearable.getDataClient(context).putDataItem(request);
Menerima aset
Ketika aset dibuat, Anda mungkin ingin membaca dan mengekstraknya di sisi lain koneksi. Berikut adalah contoh cara menerapkan callback untuk mendeteksi perubahan aset dan mengekstrak aset:
override fun onDataChanged(dataEvents: DataEventBuffer) { dataEvents .filter { it.type == DataEvent.TYPE_CHANGED && it.dataItem.uri.path == "/image" } .forEach { event -> val bitmap: Bitmap? = DataMapItem.fromDataItem(event.dataItem) .dataMap.getAsset("profileImage") .let { asset -> loadBitmapFromAsset(asset) } // Do something with the bitmap } } fun loadBitmapFromAsset(asset: Asset): Bitmap? { // Convert asset into a file descriptor and block until it's ready val assetInputStream: InputStream? = Tasks.await(Wearable.getDataClient(context).getFdForAsset(asset)) ?.inputStream return assetInputStream?.let { inputStream -> // Decode the stream into a bitmap BitmapFactory.decodeStream(inputStream) } ?: run { Log.w(TAG, "Requested an unknown Asset.") null } }
@Override public void onDataChanged(DataEventBuffer dataEvents) { for (DataEvent event : dataEvents) { if (event.getType() == DataEvent.TYPE_CHANGED && event.getDataItem().getUri().getPath().equals("/image")) { DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem()); Asset profileAsset = dataMapItem.getDataMap().getAsset("profileImage"); Bitmap bitmap = loadBitmapFromAsset(profileAsset); // Do something with the bitmap } } } public Bitmap loadBitmapFromAsset(Asset asset) { if (asset == null) { throw new IllegalArgumentException("Asset must be non-null"); } // Convert asset into a file descriptor and block until it's ready InputStream assetInputStream = Tasks.await(Wearable.getDataClient(context).getFdForAsset(asset)) .getInputStream(); if (assetInputStream == null) { Log.w(TAG, "Requested an unknown Asset."); return null; } // Decode the stream into a bitmap return BitmapFactory.decodeStream(assetInputStream); }
Untuk mengetahui informasi selengkapnya, lihat project contoh DataLayer di GitHub.