โอนข้อมูล Wear OS ไปยังอุปกรณ์เคลื่อนที่เครื่องใหม่

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

ตั้งแต่ Wear OS 4 เป็นต้นไป เมื่อผู้ใช้เชื่อมต่อกับอุปกรณ์เคลื่อนที่เครื่องใหม่ ผู้ใช้จะโอนข้อมูล Wear OS ไปยังอุปกรณ์เคลื่อนที่เครื่องใหม่ได้ ระบบจะซิงค์ข้อมูลโดยอัตโนมัติ เมื่อโอน

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

เอกสารนี้อธิบายวิธีกำหนดค่าแอป Wear OS และแอปบนอุปกรณ์เคลื่อนที่ที่ใช้ร่วมกันเพื่อรองรับสถานการณ์นี้

การเตรียมพร้อม

กระบวนการโอนข้อมูลจะจัดการออบเจ็กต์ DataItem แตกต่างกันไปตามแอปที่เป็นเจ้าของข้อมูล

ออบเจ็กต์ที่เป็นของแอป Wear OS
ระบบจะเก็บออบเจ็กต์เหล่านี้ไว้ในอุปกรณ์ Wear OS
ออบเจ็กต์ที่แอปบนอุปกรณ์เคลื่อนที่เป็นเจ้าของ

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

ทันทีหลังจากส่งมอบที่เก็บถาวรแล้ว Data Layer ของอุปกรณ์ที่สวมใส่ได้จะเรียกใช้ เครื่องมือฟัง onNodeMigrated() ในลักษณะเดียวกับที่ระบบจะแจ้งให้แอปของคุณทราบ เมื่ออุปกรณ์ Wear OS เขียนข้อมูล

เก็บรักษาข้อมูลที่โอน

แอปของคุณมีหน้าที่เก็บรักษาออบเจ็กต์ DataItem ที่โอน หลังจากส่งข้อมูลไปยังอุปกรณ์เคลื่อนที่เครื่องใหม่ไม่นาน ระบบจะลบที่เก็บถาวรออกจากอุปกรณ์เครื่องเก่า

ตรวจสอบว่าทำตามเงื่อนไขต่อไปนี้แล้ว

  1. ระบบจะติดตั้งแอปของคุณในอุปกรณ์เคลื่อนที่ทั้ง 2 เครื่องที่เกี่ยวข้องกับการ โอน
  2. แอปบนอุปกรณ์เคลื่อนที่ที่ติดตั้งในอุปกรณ์เคลื่อนที่แต่ละเครื่องมีลายเซ็นแพ็กเกจ ที่ตรงกัน

มิเช่นนั้น ระบบจะไม่นำส่งออบเจ็กต์ DataItem ที่เก็บถาวรไว้และจะทิ้งแทน

รับข้อมูลจากอุปกรณ์เคลื่อนที่เครื่องเก่า

หากต้องการรับข้อมูลในอุปกรณ์เคลื่อนที่เครื่องใหม่ที่เก็บไว้ในอุปกรณ์เคลื่อนที่เครื่องเก่า แอปบนอุปกรณ์เคลื่อนที่ต้องใช้การเรียกกลับ onNodeMigrated() ซึ่งเป็นส่วนหนึ่งของคลาส WearableListenerService โดยทำตามขั้นตอนต่อไปนี้

  1. ในไฟล์บิลด์ของแอปบนอุปกรณ์เคลื่อนที่ ให้รวมการอ้างอิงเวอร์ชันล่าสุด ของไลบรารีอุปกรณ์ที่สวมใส่ได้ในบริการ Google Play ดังนี้

    dependencies {
        ...
        implementation 'com.google.android.gms:play-services-wearable:19.0.0'
    }
  2. ประกาศและส่งออก WearableListenerService ในไฟล์ Manifest ของแอปโดยทำดังนี้

    <service
    android:name=".MyWearableListenerService"
    android:exported="true">
    <intent-filter>
        ...
        <action android:name="com.google.android.gms.wearable.NODE_MIGRATED" />
        <data android:scheme="wear" />
    </intent-filter>
    </service>
    
  3. สร้างคลาสบริการที่ขยาย WearableListenerService และลบล้าง onNodeMigrated()

    Kotlin

    class MyWearableListenerService : WearableListenerService() {
        val dataClient: DataClient = Wearable.getDataClient(this)
    
        private fun shouldHandleDataItem(nodeId: String,
                                        dataItem: DataItem): Boolean {
            // Your logic here
            return dataItem.uri.path?.startsWith("/my_feature_path/") == true
        }
    
        private fun handleDataItem(nodeId: String, dataItem: DataItem) {
            val data = dataItem.data ?: return
            val path = dataItem.uri.path ?: return
            // Your logic here
            if (data.toString().startsWith("Please restore")) {
                dataClient.putDataItem(
                    PutDataRequest.create(path).setData(data)
                )
            }
        }
    
        override fun onNodeMigrated(nodeId: String, archive: DataItemBuffer) {
            val dataItemsToHandle = mutableListOf<DataItem>()
    
            for (dataItem in archive) {
                if (shouldHandleDataItem(nodeId, dataItem)) {
                    dataItemsToHandle.add(dataItem.freeze())
                }
            }
    
            // Callback stops automatically after 20 seconds of data processing.
            // If you think you need more time, delegate to a coroutine or thread.
            runBlocking {
                for (dataItem in dataItemsToHandle) {
                    handleDataItem(nodeId, dataItem)
                }
            }
        }
    }

    Java

    public class MyWearableListenerService extends WearableListenerService {
        private final DataClient dataClient = Wearable.getDataClient(this);
    
        private boolean shouldHandleDataItem(String nodeId, DataItem dataItem) {
            // Your logic here
            return Objects.requireNonNull(dataItem.getUri().getPath())
                    .startsWith("/my_feature_path/");
        }
    
        private Task<DataItem> handleDataItem(String nodeId, DataItem dataItem) {
            byte[] data = dataItem.getData();
            String path = dataItem.getUri().getPath();
            // Your logic here
            if (data != null && path != null && Arrays.toString(data)
                    .startsWith("Please restore")) {
                assert path != null;
                return dataClient.putDataItem(
                            PutDataRequest.create(path).setData(data));
        }
    
        @Override
        public void onNodeMigrated(@NonNull String nodeId, DataItemBuffer archive) {
            List<DataItem> dataItemsToHandle = new ArrayList<>();
    
            for (DataItem dataItem : archive) {
                if (shouldHandleDataItem(nodeId, dataItem)) {
                    dataItemsToHandle.add(dataItem.freeze());
                }
            }
    
            for (dataItem in dataItemsToHandle) {
                handleDataItem(nodeId, dataItem);
            }
    
            // Callback stops automatically after 20 seconds of data processing.
            // If you think you need more time, delegate to another thread.
        }
    }