يتوافق هذا الدليل مع الإصدار 1.1.0-alpha12 من Health Connect أو الإصدارات الأحدث.
تحتوي معظم التطبيقات التي تتكامل مع Health Connect على مخزن بيانات خاص بها يُعدّ المصدر الموثوق. يوفّر Health Connect طرقًا لإبقاء تطبيقك متزامنًا.
استنادًا إلى بنية تطبيقك، قد تتضمّن عملية المزامنة بعضًا من الإجراءات التالية أو جميعها:
- إدخال بيانات جديدة أو معدَّلة من مخزن بيانات تطبيقك إلى Health Connect
- سحب تغييرات البيانات من Health Connect إلى مخزن بيانات تطبيقك
- احذف البيانات من Health Connect عند حذفها من مخزن بيانات تطبيقك.
في كل حالة، تأكَّد من أنّ عملية المزامنة تحافظ على توافق كل من Health Connect ومخزن بيانات تطبيقك.
تغذية Health Connect بالبيانات
الجزء الأول من عملية المزامنة هو نقل البيانات من مخزن بيانات تطبيقك إلى مخزن بيانات Health Connect.
تجهيز بياناتك
عادةً ما تحتوي السجلّات في مخزن بيانات تطبيقك على التفاصيل التالية:
- مفتاح فريد، مثل
UUID - إصدار أو طابع زمني
عند مزامنة البيانات مع Health Connect، يجب تحديد البيانات التي تم إدخالها أو تعديلها أو حذفها منذ آخر مزامنة، وإدخالها فقط.
كتابة البيانات في Health Connect
لإدخال البيانات في Health Connect، اتّبِع الخطوات التالية:
- الحصول على قائمة بالإدخالات الجديدة أو المعدَّلة أو المحذوفة من مخزن بيانات تطبيقك
- لكل إدخال، أنشِئ عنصر
Recordمناسبًا لنوع البيانات هذا. على سبيل المثال، يمكنك إنشاء عنصرWeightRecordللبيانات ذات الصلة بالوزن. حدِّد عنصر
Metadataمع كلRecord. ويشمل ذلكclientRecordId، وهو معرّف من مخزن بيانات تطبيقك يمكنك استخدامه لتحديد السجلّ بشكل فريد. يمكنك استخدام مفتاحك الفريد الحالي لهذا الغرض. إذا كانت بياناتك تتضمّن إصدارات، يُرجى أيضًا تقديمclientRecordVersionيتوافق مع الإصدارات المستخدَمة في بياناتك. إذا لم يكن هناك إصدار، يمكنك استخدام قيمةLongللطابع الزمني الحالي كبديل.val recordVersion = 0L // Specify as needed // The clientRecordId is an ID that you choose for your record. This // is often the same ID you use in your app's datastore. val clientRecordId = "<your-record-id>" val record = WeightRecord( metadata = Metadata.activelyRecorded( clientRecordId = clientRecordId, clientRecordVersion = recordVersion, device = Device(type = Device.TYPE_SCALE) ), weight = Mass.kilograms(62.0), time = Instant.now(), zoneOffset = ZoneOffset.UTC, ) healthConnectClient.insertRecords(listOf(record))
تعديل البيانات في Health Connect باستخدام
insertRecords. يعني تحديث البيانات أو إدراجها أنّه يتم استبدال أي بيانات حالية في Health Connect طالما أنّ قيمclientRecordIdمتوفّرة في مخزن بيانات Health Connect، وأنّ قيمةclientRecordVersionأعلى من القيمة الحالية. وإلا، تتم كتابة البيانات التي تم تحديثها كبيانات جديدة.healthConnectClient.insertRecords(arrayListOf(record))
للتعرّف على الاعتبارات العملية لإدخال البيانات، اطّلِع على أفضل الممارسات المتعلّقة بكتابة البيانات.
تخزين معرّفات Health Connect
إذا كان تطبيقك يقرأ أيضًا البيانات من Health Connect، يمكنك تخزين id في Health Connect
للسجلّات بعد إدراجها أو تعديلها. ستحتاج إلى هذا id لمعالجة عمليات الحذف عند
سحب تغييرات البيانات من Health Connect.
تعرض الدالة insertRecords سمة InsertRecordsResponse تحتوي على قائمة بقيم id.
استخدِم الردّ للحصول على معرّفات السجلّات وتخزينها.
val response = healthConnectClient.insertRecords(listOf(record)) for (recordId in response.recordIdsList) { // Store recordId to your app's datastore }
سحب البيانات من Health Connect
الجزء الثاني من عملية المزامنة هو سحب أي تغييرات في البيانات من Health Connect إلى مخزن بيانات تطبيقك. يمكن أن تشمل تغييرات البيانات التعديلات والحذف.
الحصول على رمز مميّز للتغييرات
للحصول على قائمة بالتغييرات التي يجب سحبها من Health Connect، يحتاج تطبيقك إلى تتبُّع رموز التغييرات المميّزة. ويمكنك استخدامها عند طلب التغييرات لعرض قائمة بتغييرات البيانات ورمز مميّز جديد لـ التغييرات لاستخدامه في المرة القادمة.
للحصول على رمز مميّز للتغييرات، يمكنك طلب getChangesToken وتوفير أنواع البيانات المطلوبة.
val changesToken = healthConnectClient.getChangesToken( ChangesTokenRequest(recordTypes = setOf(WeightRecord::class)) )
التحقّق من التغييرات في البيانات
بعد الحصول على رمز مميّز للتغييرات، استخدِمه للحصول على جميع التغييرات. ننصحك بإنشاء حلقة تكرار للتحقّق من جميع التغييرات ومعرفة ما إذا كانت هناك تغييرات في البيانات. في ما يلي الخطوات التي يجب اتّباعها:
- اتصِل بـ
getChangesباستخدام الرمز المميّز للحصول على قائمة التغييرات. - تحقَّق من كل تغيير لمعرفة ما إذا كان نوع التغيير هو
UpsertionChangeأوDeletionChange، ونفِّذ العمليات اللازمة.- بالنسبة إلى
UpsertionChange، يجب فقط قبول التغييرات التي لم يتم إجراؤها من خلال تطبيق الاتصال للتأكّد من عدم إعادة استيراد البيانات.
- بالنسبة إلى
- عيِّن الرمز المميّز التالي من التغييرات كرمز مميّز جديد.
- كرِّر الخطوات من 1 إلى 3 حتى لا يتبقّى أي تغييرات.
- خزِّن الرمز المميّز التالي واحتفظ به لعملية استيراد مستقبلية.
suspend fun processChanges(context: Context, token: String): String { var nextChangesToken = token do { val response = healthConnectClient.getChanges(nextChangesToken) response.changes.forEach { change -> when (change) { is UpsertionChange -> if (change.record.metadata.dataOrigin.packageName != context.packageName) { processUpsertionChange(change) } is DeletionChange -> processDeletionChange(change) } } nextChangesToken = response.nextChangesToken } while (response.hasMore) // Return and store the changes token for use next time. return nextChangesToken }
للتعرّف على الاعتبارات العملية لسحب البيانات، يُرجى الاطّلاع على أفضل الممارسات المتعلّقة بمزامنة البيانات.
معالجة التغييرات في البيانات
طبِّق التغييرات على مخزن بيانات تطبيقك. بالنسبة إلى "UpsertionChange"، استخدِم "id"
و"lastModifiedTime" من "metadata" لإدراج السجلّ أو تعديله.
بالنسبة إلى DeletionChange، استخدِم id المقدَّم لحذف السجلّ.
يتطلّب ذلك أن تكون قد خزّنت السجلّ id كما هو موضّح في مقالة
تخزين معرّفات Health Connect.
حذف البيانات من Health Connect
عندما يحذف مستخدم بياناته من تطبيقك، تأكَّد من إزالة البيانات أيضًا من Health Connect. استخدِم deleteRecords
لإجراء ذلك. تتطلّب هذه الطريقة نوع سجلّ وقائمة بقيم id وclientRecordId، ما يجعلها مناسبة لحذف بيانات متعددة دفعة واحدة. يتوفّر أيضًا deleteRecords بديل يتلقّى timeRangeFilter.
مزامنة منخفضة وقت الاستجابة من الأجهزة القابلة للارتداء
لمزامنة البيانات من جهاز لياقة بدنية قابل للارتداء مع Health Connect بوقت استجابة منخفض،
استخدِم CompanionDeviceService. تصلح هذه الطريقة للأجهزة التي تتيح إشعارات أو مؤشرات BLE GATT وتستهدف الإصدار 8.0 من نظام التشغيل Android (المستوى 26 من واجهة برمجة التطبيقات) أو الإصدارات الأحدث. يسمح الإذن CompanionDeviceService
لتطبيقك بتلقّي البيانات من الأجهزة القابلة للارتداء وكتابتها في Health Connect، حتى
عندما لا يكون التطبيق قيد التشغيل. لمزيد من التفاصيل حول أفضل الممارسات المتعلّقة بتكنولوجيا Bluetooth منخفض الطاقة، يُرجى الاطّلاع على نظرة عامة على تكنولوجيا Bluetooth منخفض الطاقة.
ربط الجهاز
أولاً، يجب أن يوجّه تطبيقك المستخدم خلال عملية لمرة واحدة لربط الجهاز القابل للارتداء بتطبيقك باستخدام CompanionDeviceManager. يمنح هذا الإجراء تطبيقك الأذونات اللازمة للتفاعل مع الجهاز. لمزيد من المعلومات، يُرجى الاطّلاع على مقالة إقران الأجهزة المصاحبة.
تعريف الخدمة في ملف البيان
بعد ذلك، عليك تعريف CompanionDeviceService في ملف بيان تطبيقك. أضِف ما يلي إلى ملف AndroidManifest.xml:
<manifest ...>
<application ...>
<service
android:name=".MyWearableService"
android:exported="true"
android:permission="android.permission.BIND_COMPANION_DEVICE_SERVICE">
<intent-filter>
<action android:name="android.companion.CompanionDeviceService" />
</intent-filter>
</service>
</application>
</manifest>
إنشاء CompanionDeviceService
أخيرًا، أنشئ فئة تمدّد CompanionDeviceService. تتولّى هذه الخدمة
الاتصال بالجهاز القابل للارتداء وتتلقّى البيانات من خلال عمليات استدعاء
BLE GATT. عند تلقّي بيانات جديدة، تتم كتابتها على الفور في Health Connect.
private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) private var healthConnectClient: HealthConnectClient? = null private var bluetoothGatt: BluetoothGatt? = null override fun onDeviceAppeared(address: String) { super.onDeviceAppeared(address) healthConnectClient = HealthConnectClient.getOrCreate(this) serviceScope.launch { val granted = healthConnectClient?.permissionController?.getGrantedPermissions() // 1. Check permissions ONCE when the device connects if (granted?.contains(HealthPermission.getWritePermission(HeartRateRecord::class)) ?: false) { // This is where you'd actually start the Bluetooth connection // bluetoothGatt = gattCallback.connect(...) } // 2. Do your initial database read readExerciseSessionAndRoute() } } private val gattCallback = object : BluetoothGattCallback() { override fun onCharacteristicChanged( gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, value: ByteArray ) { super.onCharacteristicChanged(gatt, characteristic, value) // 3. ONLY process the incoming data here val rawData = value serviceScope.launch { // parseWearableData(rawData) // insertExerciseRoute() or writeToHealthConnect() } } }
أفضل الممارسات لمزامنة البيانات
تؤثر العوامل التالية في عملية المزامنة.
انتهاء صلاحية الرمز المميّز
بما أنّ الرمز المميّز Changes غير المستخدَم تنتهي صلاحيته خلال 30 يومًا، عليك استخدام استراتيجية مزامنة تتجنّب فقدان المعلومات في هذه الحالة. يمكن أن تتضمن استراتيجيتك الأساليب التالية:
- ابحث في مخزن بيانات تطبيقك عن أحدث سجلّ تم استخدامه ويحتوي أيضًا على
idمن Health Connect. - اطلب السجلّات من Health Connect التي تبدأ بطابع زمني محدّد، ثم أدرِجها أو عدِّلها في مخزن بيانات تطبيقك.
- اطلب رمزًا مميزًا للتغييرات لحجزه للمرة التالية التي تحتاج إليها.
استراتيجيات إدارة التغييرات المقترَحة
في حال تلقّي تطبيقك رموز تغييرات مميّزة غير صالحة أو منتهية الصلاحية، ننصحك باتّباع استراتيجيات الإدارة التالية حسب تطبيقها في منطقك:
- قراءة جميع البيانات وإزالة التكرار منها هذه هي الاستراتيجية المثالية.
- تخزين الطابع الزمني لآخر مرة قرأت فيها البيانات من Health Connect
- عند انتهاء صلاحية الرمز المميّز، أعِد قراءة جميع البيانات من أحدث طابع زمني أو لآخر 30 يومًا. بعد ذلك، تتم إزالة البيانات المكرّرة من البيانات التي تمت قراءتها سابقًا باستخدام المعرّفات.
- من الأفضل تنفيذ معرّفات العملاء لأنّها مطلوبة لتعديلات البيانات.
- قراءة البيانات منذ آخر طابع زمني للقراءة فقط: يؤدي ذلك إلى بعض التناقضات في البيانات في وقت انتهاء صلاحية الرمز المميّز للتغييرات، ولكن الفترة الزمنية تكون أقصر وقد تستغرق بضع ساعات إلى بضعة أيام.
- تخزين الطابع الزمني لآخر مرة قرأت فيها البيانات من Health Connect
- عند انتهاء صلاحية الرمز المميّز، تتم قراءة جميع البيانات من هذا الطابع الزمني فصاعدًا.
- حذف بيانات آخر 30 يومًا ثم قراءتها يتوافق هذا بشكل أوثق
مع ما يحدث في التكامل الأول.
- حذف جميع البيانات التي قرأها التطبيق من Health Connect لآخر 30 يومًا
- بعد حذفها، اقرأ كل هذه البيانات مرة أخرى.
- قراءة البيانات لآخر 30 يومًا بدون إزالة التكرار هذه هي الاستراتيجية الأقل مثالية، وتؤدي إلى عرض بيانات مكررة للمستخدمين.
- حذف جميع البيانات التي قرأها التطبيق من Health Connect لآخر 30 يومًا
- السماح بالإدخالات المكرّرة
رموز مميّزة لتغييرات نوع البيانات
إذا كان تطبيقك يستهلك أكثر من نوع واحد من البيانات بشكل مستقل، استخدِم رموز مميزة منفصلة للتغييرات لكل نوع بيانات. لا تستخدِم قائمة بأنواع بيانات متعددة مع واجهة Changes Sync API إلا إذا كانت أنواع البيانات هذه تُستخدم معًا أو لا تُستخدم على الإطلاق.
عمليات القراءة في المقدّمة
لا يمكن للتطبيقات قراءة البيانات من Health Connect إلا عندما تكون نشطة في المقدّمة. عند مزامنة البيانات من Health Connect، قد ينقطع الوصول إلى Health Connect في أي وقت. على سبيل المثال، يجب أن يتعامل تطبيقك مع حالات الانقطاع في منتصف عملية المزامنة عند قراءة كمية كبيرة من البيانات من Health Connect، وأن يواصل العملية في المرة التالية التي يتم فيها فتح التطبيق.
القراءة في الخلفية
يمكنك طلب تشغيل تطبيقك في الخلفية وقراءة البيانات من Health Connect. إذا طلبت الحصول على إذن
Background Read، يمكن للمستخدم منح تطبيقك
إذن الوصول لقراءة البيانات في الخلفية.
استيراد التوقيتات
بما أنّ تطبيقك لا يمكنه تلقّي إشعارات بشأن البيانات الجديدة، تحقَّق من توفّر بيانات جديدة في نقطتَين:
- في كل مرة يصبح فيها تطبيقك نشطًا في المقدّمة في هذه الحالة، استخدِم الأحداث التي تتم في مراحل النشاط.
- بشكل دوري، عندما يكون تطبيقك في المقدّمة أبلِغ المستخدمين عند توفّر بيانات جديدة، ما يتيح لهم تحديث شاشاتهم لعرض التغييرات.