ซิงค์ข้อมูล

เอกสารนี้จะอธิบายวิธีซิงค์ข้อมูลระหว่างอุปกรณ์ 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() เพื่อสร้างชิ้นงาน ดังที่แสดงในตัวอย่างต่อไปนี้

KotlinJava
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());
}

ถัดไป ให้แนบชิ้นงานกับรายการข้อมูลด้วยเมธอด putAsset() ใน DataMap หรือ PutDataRequest จากนั้นใส่รายการข้อมูลลงในที่เก็บข้อมูลโดยใช้เมธอด putDataItem() ตามที่แสดงในตัวอย่างต่อไปนี้

ตัวอย่างต่อไปนี้ใช้ PutDataRequest

KotlinJava
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);

ตัวอย่างต่อไปนี้ใช้ PutDataMapRequest

KotlinJava
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);

รับเนื้อหา

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

KotlinJava
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);
}

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