مزامنة البيانات المستمرة

يوضّح هذا المستند كيفية مزامنة البيانات بين جهاز Wear OS باستخدام جهاز محمول باليد.

إرسال البيانات ومزامنتها مباشرةً من الشبكة

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

مزامنة البيانات باستخدام Wear OS Data Layer API

تعرض DataClient واجهة برمجة تطبيقات للمكونات لقراءة أو الكتابة في DataItem أو Asset

من الممكن ضبط عناصر البيانات والأصول أثناء عدم الاتصال بأي أجهزة. وتتم مزامنتها عندما تنشئ الأجهزة اتصالاً بالشبكة. هذه البيانات خاص بتطبيقك ولا يمكن الوصول إليه إلا من خلال تطبيقك على الأجهزة الأخرى.

  • تتم مزامنة DataItem على جميع الأجهزة في شبكة Wear OS. تكون بشكل عام صغيرة الحجم.

  • استخدِم Asset لنقل عنصر أكبر حجمًا، مثل صورة. النظام يتتبع الأصول التي تم نقلها بالفعل وينفذها إزالة التكرار تلقائيًا.

الاستماع إلى الأحداث في الخدمات

تمديد الصف الدراسي WearableListenerService. يدير النظام دورة حياة القاعدة WearableListenerService، وتكون ملزمة بالخدمة عند تحتاج إلى إرسال عناصر البيانات أو الرسائل وإلغاء ربط الخدمة في حالة عدم وجود أي عمل احتاجت.

الاستماع إلى الأحداث في الأنشطة

نفِّذ واجهة OnDataChangedListener. استخدام هذه الواجهة بدلاً من ذلك من WearableListenerService عندما تريد الاستماع إلى التغييرات فقط عند مستخدم نشط لتطبيقك.

نقل البيانات

لإرسال عناصر ثنائية كبيرة الحجم عبر نقل البلوتوث، مثل تسجيل صوتي من جهاز آخر، يمكنك إرفاق Asset إلى عنصر بيانات ثم ضع العنصر في مخزن البيانات المنسوخ.

تتعامل الأصول تلقائيًا مع التخزين المؤقت للبيانات لمنع إعادة إرسالها للحفاظ على معدل نقل بيانات البلوتوث. والنمط الشائع أن يقوم تطبيق محمول باليد بتنزيل صورة، ثم تقليصها إلى حجم مناسب لعرضها على الجهاز القابل للارتداء ونقله إلى التطبيق القابل للارتداء في ما يلي الأمثلة لتوضيح هذا النمط.

ملاحظة: على الرغم من أنّ حجم عناصر البيانات يقتصر نظريًا على 100 كيلوبايت، يمكن من الناحية العملية استخدام عناصر بيانات أكبر. بالنسبة عناصر بيانات أكبر وفصل البيانات حسب مسارات فريدة وتجنب استخدام مسار واحد لجميع البيانات. يؤثر نقل مواد العرض الكبيرة في تجربة المستخدم في العديد لذا يُرجى اختبار تطبيقاتك للمساعدة في التأكّد من أنّها تحقّق أداءً جيدًا عند نقل مواد العرض الكبيرة.

نقل مادة عرض

أنشِئ مادة العرض باستخدام إحدى الطريقتَين (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 ثم ضع عنصر البيانات في مخزن البيانات باستخدام 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.