همگام سازی داده ها

این سند نحوه همگام‌سازی داده‌ها بین یک دستگاه Wear OS و یک دستگاه دستی را شرح می‌دهد.

ارسال و همگام‌سازی داده‌ها مستقیماً از شبکه

برنامه‌های Wear OS را طوری بسازید که مستقیماً با شبکه ارتباط برقرار کنند . از همان APIهایی که برای توسعه موبایل استفاده می‌کنید استفاده کنید، اما برخی از تفاوت‌های خاص Wear-OS را در نظر داشته باشید.

همگام‌سازی داده‌ها با استفاده از API لایه داده Wear OS

یک DataClient یک API را در اختیار کامپوننت‌ها قرار می‌دهد تا یک DataItem یا Asset را بخوانند یا در آن بنویسند.

می‌توان اقلام داده و دارایی‌ها را بدون اتصال به هیچ دستگاهی تنظیم کرد. آن‌ها زمانی که دستگاه‌ها به شبکه متصل می‌شوند، همگام‌سازی می‌شوند. این داده‌ها برای برنامه شما خصوصی هستند و فقط در دستگاه‌های دیگر برای برنامه شما قابل دسترسی هستند.

  • یک DataItem در تمام دستگاه‌های موجود در شبکه Wear OS همگام‌سازی می‌شود. آن‌ها معمولاً اندازه کوچکی دارند.

  • از یک Asset برای انتقال یک شیء بزرگتر، مانند یک تصویر، استفاده کنید. سیستم پیگیری می‌کند که کدام دارایی‌ها قبلاً منتقل شده‌اند و به‌طور خودکار حذف داده‌های تکراری را انجام می‌دهد.

به رویدادها در خدمات گوش دهید

کلاس WearableListenerService را ارث‌بری کنید. این سیستم چرخه حیات WearableListenerService پایه را مدیریت می‌کند، زمانی که نیاز به ارسال اقلام داده یا پیام باشد، به سرویس متصل می‌شود و زمانی که نیازی به کار نباشد، سرویس را از حالت اتصال خارج می‌کند.

به رویدادها در فعالیت‌ها گوش دهید

رابط OnDataChangedListener پیاده‌سازی کنید. از این رابط به جای WearableListenerService زمانی استفاده کنید که می‌خواهید فقط زمانی که کاربر به طور فعال از برنامه شما استفاده می‌کند، به تغییرات گوش دهید.

انتقال داده

برای ارسال اشیاء بزرگ باینری از طریق انتقال بلوتوث، مانند ضبط صدا از دستگاه دیگر، می‌توانید یک Asset را به یک آیتم داده پیوست کنید و سپس آیتم داده را در مخزن داده تکثیر شده قرار دهید.

دارایی‌ها به طور خودکار داده‌ها را ذخیره می‌کنند تا از ارسال مجدد جلوگیری کرده و پهنای باند بلوتوث را حفظ کنند. یک الگوی رایج برای یک برنامه دستی این است که یک تصویر را دانلود کند، آن را به اندازه مناسب برای نمایش در دستگاه پوشیدنی کوچک کند و آن را به عنوان یک دارایی به برنامه پوشیدنی منتقل کند. مثال‌های زیر این الگو را نشان می‌دهند.

توجه: اگرچه اندازه اقلام داده از نظر تئوری به ۱۰۰ کیلوبایت محدود می‌شود، اما در عمل می‌توان از اقلام داده بزرگتر استفاده کرد. برای اقلام داده بزرگتر، داده‌ها را با مسیرهای منحصر به فرد جدا کنید و از استفاده از یک مسیر واحد برای همه داده‌ها خودداری کنید. انتقال دارایی‌های بزرگ در بسیاری از موارد بر تجربه کاربر تأثیر می‌گذارد، بنابراین برنامه‌های خود را آزمایش کنید تا از عملکرد خوب آنها هنگام انتقال دارایی‌های بزرگ اطمینان حاصل کنید.

انتقال یک دارایی

با استفاده از یکی از متدهای create...() در کلاس Asset ، دارایی را ایجاد کنید. یک بیت‌مپ را به یک جریان بایت تبدیل کنید و سپس createFromBytes() را برای ایجاد دارایی فراخوانی کنید، همانطور که در نمونه زیر نشان داده شده است.

کاتلین

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() در datastore قرار دهید، همانطور که در نمونه‌های زیر نشان داده شده است.

نمونه زیر از PutDataRequest استفاده می‌کند:

کاتلین

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 استفاده می‌کند:

کاتلین

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

دریافت دارایی‌ها

وقتی یک دارایی ایجاد می‌شود، احتمالاً می‌خواهید آن را در طرف دیگر اتصال بخوانید و استخراج کنید. در اینجا مثالی از نحوه پیاده‌سازی فراخوانی برای تشخیص تغییر دارایی و استخراج دارایی آورده شده است:

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(this).getFdForAsset(asset))
            ?.inputStream

    return assetInputStream?.let { inputStream ->
        // Decode the stream into a bitmap
        BitmapFactory.decodeStream(inputStream)
    } ?: run {
        // Requested an unknown asset
        null
    }
}

برای اطلاعات بیشتر، به نمونه پروژه DataLayer در GitHub مراجعه کنید.