ซิงค์ข้อมูล

เอกสารนี้อธิบายวิธีซิงค์ข้อมูลระหว่างอุปกรณ์ Wear OS กับอุปกรณ์พกพา

ส่งและซิงค์ข้อมูลจากเครือข่ายโดยตรง

สร้างแอป Wear OS เพื่อ สื่อสารกับเครือข่ายโดยตรง ใช้ API เดียวกับที่ใช้สำหรับการพัฒนาแอปบนมือถือ แต่คำนึงถึงความแตกต่างบางอย่างที่เฉพาะเจาะจงกับ Wear OS

ซิงค์ข้อมูลโดยใช้ Wear OS Data Layer API

DataClient แสดง API ให้คอมโพเนนต์อ่านหรือเขียนไปยัง DataItem หรือ Asset

คุณสามารถตั้งค่ารายการข้อมูลและเนื้อหาได้แม้ว่าจะไม่ได้เชื่อมต่อกับอุปกรณ์ใดๆ ระบบจะซิงค์รายการข้อมูลและเนื้อหาเมื่ออุปกรณ์สร้างการเชื่อมต่อเครือข่าย ข้อมูลนี้จะเป็นข้อมูลส่วนตัวของแอปและแอปของคุณเท่านั้นที่จะเข้าถึงได้ในอุปกรณ์อื่นๆ

  • ระบบจะซิงค์ DataItem ในอุปกรณ์ทั้งหมดในเครือข่าย Wear OS โดยทั่วไปแล้วจะมีขนาดเล็ก

  • ใช้ Asset เพื่อโอนออบเจ็กต์ขนาดใหญ่ขึ้น เช่น รูปภาพ ระบบจะติดตามเนื้อหาที่โอนแล้วและทำการหักล้างข้อมูลที่ซ้ำกันโดยอัตโนมัติ

รับฟังเหตุการณ์ในบริการ

ขยายคลาส WearableListenerService ระบบจะจัดการวงจรของ WearableListenerService พื้นฐาน โดยเชื่อมโยงกับบริการเมื่อต้องส่งรายการข้อมูลหรือข้อความ และยกเลิกการเชื่อมโยงบริการเมื่อไม่จำเป็นต้องดำเนินการ

รับฟังเหตุการณ์ในกิจกรรม

ใช้อินเทอร์เฟซ OnDataChangedListener ใช้อินเทอร์เฟซนี้แทน WearableListenerService เมื่อต้องการรับฟังการเปลี่ยนแปลงเฉพาะเมื่อผู้ใช้ใช้งานแอปของคุณอยู่

โอนข้อมูล

หากต้องการส่ง Binary Large Object ผ่านการขนส่ง Bluetooth เช่น การบันทึกเสียง จากอุปกรณ์อื่น คุณสามารถแนบ Asset กับรายการข้อมูล แล้วใส่รายการข้อมูลลงใน Datastore ที่จำลองขึ้น

เนื้อหาจะจัดการการแคชข้อมูลโดยอัตโนมัติเพื่อป้องกันการส่งซ้ำและ ประหยัดแบนด์วิดท์ Bluetooth รูปแบบที่ใช้กันทั่วไปคือแอปแบบพกพาจะดาวน์โหลดรูปภาพ ย่อขนาดให้เหมาะสมกับการแสดงผลในอุปกรณ์สวมใส่ และส่งไปยังแอปสำหรับอุปกรณ์สวมใส่เป็นเนื้อหา ตัวอย่างต่อไปนี้ แสดงรูปแบบนี้

หมายเหตุ: แม้ว่าขนาดของรายการข้อมูลจะจำกัดไว้ที่ 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);

รับเนื้อหา

เมื่อสร้างเนื้อหาแล้ว คุณอาจต้องการอ่านและแยกเนื้อหาในอีกด้านหนึ่งของการเชื่อมต่อ ตัวอย่างต่อไปนี้แสดงวิธีใช้ Callback เพื่อตรวจหาการเปลี่ยนแปลงเนื้อหาและแยกเนื้อหา

override fun onDataChanged(dataEvents: DataEventBuffer) {
    dataEvents
        .filter { it.type == DataEvent.TYPE_CHANGED && it.dataItem.uri.path == "/image" }
        .forEach { event ->
            val asset = DataMapItem.fromDataItem(event.dataItem)
                .dataMap.getAsset("profileImage")

            asset?.let { safeAsset ->
                lifecycleScope.launch {
                    val bitmap = loadBitmapFromAsset(safeAsset)
                    // Do something with the bitmap
                }
            }
        }
}

private suspend fun loadBitmapFromAsset(asset: Asset): Bitmap? = withContext(Dispatchers.IO) {
    try {
        val assetResult = Wearable.getDataClient(this@DataLayerActivity2)
            .getFdForAsset(asset)
            .await()

        assetResult?.inputStream?.use { inputStream ->
            BitmapFactory.decodeStream(inputStream)
        }
    } catch (e: Exception) {
        e.printStackTrace()
        null
    }
}

ดูข้อมูลเพิ่มเติมได้ที่โปรเจ็กต์ตัวอย่าง DataLayer ใน GitHub