يوضّح هذا المستند كيفية مزامنة البيانات بين جهاز 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.