نقل بيانات Wear OS إلى جهاز جوّال جديد

عند إعداد جهاز Wear OS بواسطة المستخدمين، يتم ربط جهاز Wear OS بجهاز جوّال معيّن. قد يقرر المستخدم لاحقًا الحصول على جهاز جوّال جديد وربط جهاز Wear OS الحالي بهذا الجهاز الجوّال الجديد. يتم تخزين بعض البيانات المرتبطة بجهاز Wear OS على الجهاز الجوّال المتصل حاليًا.

بدءًا من نظام التشغيل Wear OS 4، عندما يتصل المستخدمون بجهاز جوّال جديد، يمكنهم نقل بيانات Wear OS إلى الجهاز الجوّال الجديد. تتم مزامنة البيانات تلقائيًا عند نقلها.

عندما يطلب المستخدم عملية نقل، ترسل طبقة البيانات القابلة للارتداء عناصر DataItem، التي تم تخزينها في الأصل على أحد الأجهزة الجوّالة، إلى الجهاز الجوّال الآخر. يتيح ذلك توفير تجربة سلسة لمستخدمي تطبيقك.

يوضّح هذا المستند كيفية إعداد تطبيق Wear OS وتطبيق الأجهزة الجوّالة المصاحب له للتوافق مع هذا السيناريو.

الإعداد

تتعامل عملية نقل البيانات مع عناصر DataItem بشكل مختلف، بناءً على التطبيق الذي يملك البيانات:

العناصر التي يمتلكها تطبيق Wear OS
يتم حفظ هذه العناصر على جهاز Wear OS.
العناصر التي يمتلكها تطبيق الأجهزة الجوّالة

تمت أرشفة هذه العناصر على الجهاز القديم. بعد ذلك، يحزم النظام البيانات المؤرشفة في عنصر DataItemBuffer ويسلّم هذه البيانات إلى التطبيق المتوافق مع الأجهزة الجوّالة المثبَّت على الجهاز الجوّال الجديد.

بعد تسليم الأرشيف مباشرةً، تستدعي طبقة البيانات القابلة للارتداء أداة معالجة البيانات في onDataChanged()، تمامًا كما يتم إشعار تطبيقك عندما تتم كتابة البيانات بواسطة جهاز Wear OS.

الاحتفاظ بالبيانات المنقولة

تقع على عاتق تطبيقك مسؤولية الحفاظ على عناصر DataItem التي تم نقلها. بعد وقت قصير من تسليم البيانات إلى الجهاز الجوّال الجديد، يتم حذف الأرشيف من الجهاز القديم.

تأكد من صحة كل شرط من الشروط التالية:

  1. أن يتم تثبيت تطبيقك على كلٍّ من الأجهزة الجوّالة المعنيّة بعملية النقل
  2. تحتوي تطبيقات الهاتف المحمول، المثبتة على كل جهاز محمول، على توقيعات حزم متطابقة.

وفي حال عدم تنفيذ ذلك، لا يتم تسليم كائنات DataItem المؤرشفة ويتم تجاهلها بدلاً من ذلك.

تلقي البيانات من الجهاز الجوّال القديم

لتلقّي البيانات على الجهاز الجوّال الجديد التي تمت أرشفتها على الجهاز الجوّال القديم، يجب أن ينفِّذ تطبيقك للأجهزة الجوّالة معاودة الاتصال onNodeMigrated()، وهي جزء من الفئة WearableListenerService. للقيام بذلك، أكمل الخطوات التالية:

  1. في ملف إصدار التطبيق للأجهزة الجوّالة، ضمِّن اعتمادية على أحدث إصدار من المكتبة القابلة للارتداء في خدمات Google Play:

    dependencies {
        ...
        implementation 'com.google.android.gms:play-services-wearable:18.1.0'
    }
    
  2. يمكنك تعريف WearableListenerService وتصديره في ملف البيان لتطبيقك:

    <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 suspend 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())
                }
            }
    
            CoroutineScope(Job() + Dispatchers.IO).launch {
                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 void 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;
                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());
                }
            }
    
            Thread thread = new Thread(() -> {
                for (DataItem dataItem : dataItemsToHandle) {
                    handleDataItem(nodeId, dataItem);
                }
            });
            thread.start();
        }
    }