เอกสารนี้จะอธิบายวิธีซิงค์ข้อมูลระหว่างอุปกรณ์ Wear OS กับอุปกรณ์พกพา
ส่งและซิงค์ข้อมูลจากเครือข่ายโดยตรง
สร้างแอป Wear OS เพื่อสื่อสารกับเครือข่ายโดยตรง ใช้ API เดียวกันกับที่ใช้สำหรับการพัฒนาแอปบนอุปกรณ์เคลื่อนที่ แต่โปรดคำนึงถึงความแตกต่างบางอย่างที่เฉพาะเจาะจงสำหรับ Wear OS
ซิงค์ข้อมูลโดยใช้ Wear OS Data Layer API
DataClient
จะแสดง API ให้คอมโพเนนต์อ่านหรือเขียนไปยัง DataItem
หรือ
Asset
คุณตั้งค่ารายการข้อมูลและชิ้นงานได้ในขณะที่ไม่ได้เชื่อมต่อกับอุปกรณ์ใดๆ ระบบจะซิงค์ข้อมูลเมื่ออุปกรณ์สร้างการเชื่อมต่อเครือข่าย ข้อมูลนี้ จะเป็นข้อมูลส่วนตัวของแอปและแอปของคุณจะเข้าถึงได้ในอุปกรณ์อื่นๆ เท่านั้น
ระบบจะซิงค์
DataItem
ในอุปกรณ์ทั้งหมดในเครือข่าย Wear OS โดยทั่วไปแล้วจะมีขนาดเล็กใช้
Asset
เพื่อโอนออบเจ็กต์ขนาดใหญ่ขึ้น เช่น รูปภาพ ระบบ จะติดตามเนื้อหาที่โอนแล้วและ ขจัดข้อมูลที่ซ้ำกันโดยอัตโนมัติ
ฟังเหตุการณ์ในบริการ
ขยายคลาส WearableListenerService
ระบบจะจัดการวงจร
ของ WearableListenerService
ฐาน โดยผูกกับบริการเมื่อ
ต้องส่งรายการข้อมูลหรือข้อความ และยกเลิกการผูกบริการเมื่อไม่จำเป็นต้อง
ทำงาน
ฟังเหตุการณ์ในกิจกรรม
ใช้OnDataChangedListener
อินเทอร์เฟซ ใช้อินเทอร์เฟซนี้แทน WearableListenerService
เมื่อต้องการฟังการเปลี่ยนแปลงเฉพาะเมื่อผู้ใช้ใช้งานแอปของคุณอยู่เท่านั้น
โอนข้อมูล
หากต้องการส่งออบเจ็กต์ไบนารีขนาดใหญ่ผ่านการรับส่งบลูทูธ เช่น บันทึกเสียง
จากอุปกรณ์อื่น คุณสามารถแนบ
Asset
ไปยังรายการข้อมูล แล้วใส่รายการข้อมูลลงในที่เก็บข้อมูลที่จำลอง
โดยเนื้อหาจะจัดการแคชข้อมูลโดยอัตโนมัติเพื่อป้องกันการส่งซ้ำและ เพื่อประหยัดแบนด์วิดท์ของบลูทูธ รูปแบบที่พบบ่อยคือแอปที่ใช้มือถือจะดาวน์โหลดรูปภาพ ย่อให้มีขนาดที่เหมาะสม เพื่อแสดงบนอุปกรณ์ที่สวมใส่ได้ และส่งไปยังแอปบนอุปกรณ์ที่สวมใส่ได้เป็นเนื้อหา ตัวอย่างต่อไปนี้ แสดงรูปแบบนี้
หมายเหตุ: แม้ว่าในทางทฤษฎีแล้วขนาดของรายการข้อมูลจะจำกัดไว้ที่ 100 KB แต่ในทางปฏิบัติก็สามารถใช้รายการข้อมูลที่มีขนาดใหญ่กว่านั้นได้ สำหรับ รายการข้อมูลขนาดใหญ่ ให้แยกข้อมูลตามเส้นทางที่ไม่ซ้ำกันและหลีกเลี่ยง การใช้เส้นทางเดียวสำหรับข้อมูลทั้งหมด การโอนเนื้อหาขนาดใหญ่อาจส่งผลต่อประสบการณ์ของผู้ใช้ในหลายกรณี ดังนั้นโปรดทดสอบแอปเพื่อให้แน่ใจว่าแอปทำงานได้ดีเมื่อโอนเนื้อหาขนาดใหญ่
โอนเนื้อหา
สร้างเนื้อหาโดยใช้วิธีการ create...()
อย่างใดอย่างหนึ่งในคลาส
Asset
แปลงบิตแมปเป็นสตรีมไบต์ แล้วเรียกใช้
createFromBytes()
เพื่อสร้างชิ้นงาน ดังที่แสดงในตัวอย่างต่อไปนี้
Kotlin
private fun createAssetFromBitmap(bitmap: Bitmap): Asset = ByteArrayOutputStream().let { byteStream -> bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream) Asset.createFromBytes(byteStream.toByteArray()) }
Java
private static Asset createAssetFromBitmap(Bitmap bitmap) { final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream); return Asset.createFromBytes(byteStream.toByteArray()); }
จากนั้นแนบชิ้นงานกับรายการข้อมูลด้วยเมธอด putAsset()
ใน
DataMap
หรือ
PutDataRequest
จากนั้นใส่รายการข้อมูลลงใน Datastore โดยใช้วิธี
putDataItem()
ดังที่แสดงในตัวอย่างต่อไปนี้
ตัวอย่างต่อไปนี้ใช้ PutDataRequest
Kotlin
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)
Java
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);
ตัวอย่างต่อไปนี้ใช้ PutDataMapRequest
Kotlin
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)
Java
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);
รับเนื้อหา
เมื่อสร้างชิ้นงานแล้ว คุณอาจต้องการอ่านและแยก ชิ้นงานนั้นในอีกด้านหนึ่งของการเชื่อมต่อ ตัวอย่างวิธีใช้ การเรียกกลับเพื่อตรวจหาการเปลี่ยนแปลงของเนื้อหาและแยกเนื้อหา
Kotlin
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 } }
Java
@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); }
ดูข้อมูลเพิ่มเติมได้ที่โปรเจ็กต์ตัวอย่าง DataLayer ใน GitHub