يتوافق هذا الدليل مع الإصدار 1.1.0-alpha12 من Health Connect.
يغطّي هذا الدليل عملية كتابة البيانات أو تعديلها في Health Connect.
التعامل مع القيم الصفرية
قد تكون قيمة بعض أنواع البيانات، مثل الخطوات أو المسافة أو السعرات الحرارية، هي 0.
لا تكتب قيمًا صفرية إلا عندما تعكس عدم النشاط الفعلي أثناء ارتداء المستخدم للجهاز. لا تكتب قيمًا صفرية إذا لم يكن الجهاز مرتديًا أو كانت البيانات مفقودة أو نفدت البطارية. في مثل هذه الحالات، احذف السجلّ لتجنُّب البيانات المضلّلة.
إعداد بنية البيانات
قبل كتابة البيانات، علينا إعداد السجلات أولاً. بالنسبة إلى أكثر من 50 نوعًا من البيانات، لكل منها بنيته الخاصة. يمكنك الاطّلاع على مرجع Jetpack للحصول على مزيد من التفاصيل حول أنواع البيانات المتاحة.
السجلات الأساسية
يسجّل نوع بيانات الخطوات في Health Connect عدد الخطوات التي اتّخذها المستخدم بين القراءات. تمثّل أعداد الخطوات مقياسًا شائعًا في جميع منصات الصحة واللياقة البدنية والعافية.
يوضّح المثال التالي كيفية ضبط بيانات عدد الخطوات:
val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(startTime) val stepsRecord = StepsRecord( count = 120, startTime = startTime, endTime = endTime, startZoneOffset = zoneOffset, endZoneOffset = zoneOffset, metadata = Metadata.autoRecorded( device = Device(type = Device.TYPE_WATCH) ) ) healthConnectClient.insertRecords(listOf(stepsRecord))
السجلات التي تتضمّن وحدات قياس
يمكن لتطبيق Health Connect تخزين القيم مع وحدات القياس الخاصة بها لضمان الدقة. أحد الأمثلة على ذلك هو نوع البيانات التغذية الذي يتضمّن معلومات واسعة النطاق وشاملة. وتشمل مجموعة متنوعة من حقول العناصر الغذائية الاختيارية، بدءًا من إجمالي الكربوهيدرات وصولاً إلى الفيتامينات. تمثّل كل نقطة بيانات العناصر الغذائية التي تم استهلاكها كجزء من وجبة أو طبق.
في نوع البيانات هذا، يتم تمثيل جميع العناصر الغذائية بوحدات كتلة، بينما يتم تمثيل energy بوحدة طاقة.
يوضّح المثال التالي كيفية ضبط بيانات التغذية لمستخدم تناول موزة:
val endTime = Instant.now() val startTime = endTime.minus(Duration.ofMinutes(1)) val banana = NutritionRecord( name = "banana", energy = 105.0.kilocalories, dietaryFiber = 3.1.grams, potassium = 0.422.grams, totalCarbohydrate = 27.0.grams, totalFat = 0.4.grams, saturatedFat = 0.1.grams, sodium = 0.001.grams, sugar = 14.0.grams, vitaminB6 = 0.0005.grams, vitaminC = 0.0103.grams, startTime = startTime, endTime = endTime, startZoneOffset = ZoneOffset.UTC, endZoneOffset = ZoneOffset.UTC, metadata = Metadata.activelyRecorded( device = Device(type = Device.TYPE_PHONE) ) )
السجلات التي تتضمّن بيانات السلسلة
يمكن لتطبيق Health Connect تخزين قائمة ببيانات السلسلة. أحد الأمثلة على ذلك هو نوع البيانات معدّل نبضات القلب الذي يسجّل سلسلة من عيّنات نبضات القلب التي تم رصدها بين القراءات.
في نوع البيانات هذا، يتم تمثيل المَعلمة samples بقائمة من عيّنات معدّل نبضات القلب. تحتوي كل عيّنة على قيمة beatsPerMinute
وقيمة time.
يوضّح المثال التالي كيفية ضبط بيانات سلسلة معدّل ضربات القلب:
val endTime = Instant.now() val startTime = endTime.minus(Duration.ofMinutes(5)) val heartRateRecord = HeartRateRecord( startTime = startTime, startZoneOffset = ZoneOffset.UTC, endTime = endTime, endZoneOffset = ZoneOffset.UTC, // records 10 arbitrary data, to replace with actual data samples = List(10) { index -> HeartRateRecord.Sample( time = startTime + Duration.ofSeconds(index.toLong()), beatsPerMinute = 100 + index.toLong(), ) }, metadata = Metadata.activelyRecorded( device = Device(type = Device.TYPE_WATCH) ))
طلب الأذونات من المستخدم
بعد إنشاء مثيل العميل، يحتاج تطبيقك إلى طلب الأذونات من المستخدم. يجب السماح للمستخدمين بمنح الأذونات أو رفضها في أي وقت. لإجراء ذلك، أنشئ مجموعة من الأذونات لأنواع البيانات المطلوبة. تأكَّد أولاً من تضمين الأذونات في المجموعة في بيان Android.
val permissions = setOf( HealthPermission.getReadPermission(HeartRateRecord::class), HealthPermission.getWritePermission(HeartRateRecord::class), HealthPermission.getReadPermission(StepsRecord::class), HealthPermission.getWritePermission(StepsRecord::class) )
getGrantedPermissions
لمعرفة ما إذا كان تطبيقك قد حصل على الأذونات المطلوبة. إذا لم يكن الأمر كذلك، استخدِم
createRequestPermissionResultContract
لطلب هذه الأذونات. سيؤدي ذلك إلى عرض شاشة أذونات Health Connect.
val permissions = setOf( HealthPermission.getReadPermission(StepsRecord::class), HealthPermission.getWritePermission(StepsRecord::class), HealthPermission.getReadPermission(HeartRateRecord::class), HealthPermission.getWritePermission(HeartRateRecord::class) ) val requestPermissionsLauncher = rememberLauncherForActivityResult( contract = PermissionController.createRequestPermissionResultContract() ) { grantedPermissions -> if (grantedPermissions.containsAll(permissions)) { coroutineScope.launch { snackbarHostState.showSnackbar("Permissions granted!") } } else { coroutineScope.launch { snackbarHostState.showSnackbar("Permissions denied.") } } }
كتابة البيانات
أحد إجراءات سير العمل الشائعة في Health Connect هو كتابة البيانات. لإضافة سجلات، استخدِم insertRecords.
يوضّح المثال التالي كيفية كتابة بيانات إدراج عدد الخطوات:
val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(startTime) val stepsRecord = StepsRecord( count = 120, startTime = startTime, endTime = endTime, startZoneOffset = zoneOffset, endZoneOffset = zoneOffset, metadata = Metadata.autoRecorded( device = Device(type = Device.TYPE_WATCH) ) ) healthConnectClient.insertRecords(listOf(stepsRecord))
تعديل البيانات
إذا كنت بحاجة إلى تغيير سجلّ واحد أو أكثر، خاصةً عندما تحتاج إلى مزامنة مخزن بيانات تطبيقك مع بيانات من Health Connect، يمكنك تعديل بياناتك. هناك طريقتان لتعديل البيانات الحالية، ويعتمد ذلك على المعرّف المستخدَم للعثور على السجلات.
البيانات الوصفية
من المفيد فحص الفئة Metadata أولاً لأنّها ضرورية عند تعديل البيانات. عند إنشاء كل Record في Health Connect، يتم إنشاء حقل metadata. في ما يلي السمات ذات الصلة بالمزامنة:
| الخصائص | الوصف |
|---|---|
id
|
يحتوي كل Record في Health Connect على قيمة id فريدة.يملأ تطبيق Health Connect هذا الحقل تلقائيًا عند إدراج سجلّ جديد. |
lastModifiedTime
|
يتتبّع كل Record أيضًا آخر مرة تم فيها تعديل السجلّ.يملأ تطبيق Health Connect هذا الحقل تلقائيًا. |
clientRecordId
|
يمكن أن يتضمّن كل Record معرّفًا فريدًا مرتبطًا به ليتم استخدامه كمرجع في مستودع بيانات تطبيقك.
يوفّر تطبيقك هذه القيمة. |
clientRecordVersion
|
في حال احتواء السجلّ على clientRecordId، يمكن استخدام clientRecordVersion للسماح بمزامنة البيانات مع الإصدار في مستودع بيانات التطبيق.يوفّر تطبيقك هذه القيمة. |
تعديل بعد القراءة حسب النطاق الزمني
لتعديل البيانات، عليك إعداد السجلات المطلوبة أولاً. أجرِ أي تغييرات على السجلات إذا لزم الأمر. بعد ذلك، استدعِ الدالة updateRecords لإجراء التغييرات.
يوضّح المثال التالي كيفية تعديل البيانات. لهذا الغرض، يتم تعديل قيم إزاحة المنطقة الزمنية لكل سجلّ لتصبح بتوقيت المحيط الهادئ الرسمي.
suspend fun updateSteps( healthConnectClient: HealthConnectClient, prevRecordStartTime: Instant, prevRecordEndTime: Instant ) { try { val request = healthConnectClient.readRecords( ReadRecordsRequest( recordType = StepsRecord::class, timeRangeFilter = TimeRangeFilter.between( prevRecordStartTime, prevRecordEndTime ) ) ) val newStepsRecords = arrayListOf<StepsRecord>() for (record in request.records) { // Adjusted both offset values to reflect changes val sr = StepsRecord( count = record.count, startTime = record.startTime, startZoneOffset = record.startTime.atZone(ZoneId.of("PST")).offset, endTime = record.endTime, endZoneOffset = record.endTime.atZone(ZoneId.of("PST")).offset, metadata = record.metadata ) newStepsRecords.add(sr) } healthConnectClient.updateRecords(newStepsRecords) } catch (e: Exception) { // Run error handling here } }
إجراء عملية إدراج أو تعديل من خلال معرّف سجلّ العميل
إذا كنت تستخدم القيم الاختيارية "رقم تعريف سجلّ العميل" و"إصدار سجلّ العميل"، ننصحك باستخدام insertRecords بدلاً من updateRecords.
تتضمّن الدالة insertRecords إمكانية إدراج البيانات أو تعديلها.
إذا كانت البيانات متوفّرة في Health Connect استنادًا إلى مجموعة معرّفات سجلّات العميل المحدّدة، سيتم استبدالها. بخلاف ذلك، يتم تسجيلها كبيانات جديدة.
يكون هذا السيناريو مفيدًا عندما تحتاج إلى مزامنة البيانات من مستودع بيانات تطبيقك مع Health Connect.
يوضّح المثال التالي كيفية إجراء عملية إدراج أو تعديل على البيانات التي تم استردادها من مستودع بيانات التطبيق:
fun pullStepsFromDatastore(startTime: Instant, endTime: Instant) : ArrayList<StepsRecord> { val appStepsRecords = arrayListOf<StepsRecord>() // Pull data from app datastore // ... // Make changes to data if necessary // ... // Store data in appStepsRecords // ... var sr = StepsRecord( metadata = Metadata.activelyRecorded( clientRecordId = "Your client record ID", clientRecordVersion = 0L, device = Device(type = Device.TYPE_WATCH) ), startTime = startTime, startZoneOffset = startTime.atZone(ZoneId.of("PST")).offset, endTime = endTime, endZoneOffset = endTime.atZone(ZoneId.of("PST")).offset, count = 120 ) appStepsRecords.add(sr) // ... return appStepsRecords } suspend fun upsertSteps( healthConnectClient: HealthConnectClient, newStepsRecords: ArrayList<StepsRecord> ) { try { healthConnectClient.insertRecords(newStepsRecords) } catch (e: Exception) { // Run error handling here } }
بعد ذلك، يمكنك استدعاء هذه الدوال في سلسلة التعليمات الرئيسية.
upsertSteps(healthConnectClient, pullStepsFromDatastore( startTime = startTime, endTime = endTime ))
التحقّق من القيمة في إصدار سجلّ العميل
إذا كانت عملية إدراج البيانات أو تعديلها تتضمّن Client Record Version، سيُجري تطبيق Health Connect عمليات تحقّق من المطابقة في clientRecordVersion
القيم. إذا كان الإصدار من البيانات المُدرَجة أعلى من الإصدار من البيانات الحالية، سيتم إجراء عملية الإدراج والتعديل. بخلاف ذلك، تتجاهل العملية التغيير وتبقى القيمة كما هي.
لتضمين معلومات حول الإصدارات في بياناتك، عليك تقديم Metadata.clientRecordVersion مع قيمة Long استنادًا إلى منطق تحديد الإصدارات.
val endTime = Instant.now() val startTime = endTime.minus(Duration.ofMinutes(15)) val stepsRecord = StepsRecord( count = 100L, startTime = startTime, startZoneOffset = ZoneOffset.UTC, endTime = endTime, endZoneOffset = ZoneOffset.UTC, metadata = Metadata.activelyRecorded( clientRecordId = "Your supplied record ID", clientRecordVersion = 0L, // Your supplied record version device = Device(type = Device.TYPE_WATCH) ) )
لا تزيد عمليات الإدراج والتعديل تلقائيًا قيمة version عند حدوث أي تغييرات، ما يمنع أي حالات غير متوقّعة من الكتابة فوق البيانات. وبالتالي، عليك تقديم قيمة أعلى يدويًا.
إرشادات عامة
يجب أن يكتب تطبيقك جميع بيانات الطرف الأول المتوافقة. يمكنك اختياريًا السماح لتطبيقك بكتابة البيانات التي تم الحصول عليها من مصادر تابعة لجهات خارجية. ومع ذلك، إذا كان تطبيقك قد قرأ بيانات من Health Connect، يجب ألا تتم إعادة كتابة هذه البيانات في Health Connect.
عند كتابة بيانات تم استيرادها أو استخلاصها من مصدر آخر، عليك تحديد مصدرها بشكل صحيح وتضمين البيانات الوصفية لجهاز المصدر. لإجراء ذلك، يجب تقديم البيانات الوصفية التالية لكل سجلّ مكتوب:
recordingMethod: بالنسبة إلى البيانات المسجّلة تلقائيًا أو يدويًا، نتوقّع أن يتم تعديل طريقة التسجيل لتعكس نوع النشاط الذي تم تسجيله:RECORDING_METHOD_AUTOMATICALLY_RECORDED: إذا تم تسجيل البيانات تلقائيًا، مثلاً، إذا رصد سوار اللياقة البدنية تلقائيًا أنّ المستخدم ذهب للركض.RECORDING_METHOD_ACTIVELY_RECORDED: إذا بدأ المستخدم نشاطًا جديدًا، مثل ركوب الدراجة على الجهاز القابل للارتداء-
RECORDING_METHOD_MANUAL_ENTRY: إذا أدخل المستخدم البيانات يدويًا
device.type: يجب تحديد نوع جهاز من بين أنواعDeviceالمتوافقة.- استبدِل
device.manufacturerباسم الشركة المصنّعة للجهاز، مثلاً "Fitbit". device.model: طراز الجهاز، مثل "Charge 3".device.udi: (اختياري) جزء معرّف الجهاز (DI) من رقم التعريف الفريد للجهاز (UDI) الخاص بالجهاز الطبي. للاطّلاع على تفاصيل حول الإذن المطلوب وإرشادات الخصوصية، يُرجى الرجوع إلى دليل البيانات الوصفية.
يُعدّ ضبط البيانات الوصفية بشكل صحيح أمرًا بالغ الأهمية لضمان شفافية البيانات، ويساعد المستخدمين في معرفة مصدر معلوماتهم الصحية. للحصول على التفاصيل الكاملة، يُرجى الرجوع إلى دليل البيانات الوصفية في Health Connect.
إذا تم استيراد البيانات في تطبيقك من تطبيق آخر، يكون التطبيق الآخر هو المسؤول عن كتابة بياناته في Health Connect.
من المستحسن أيضًا تنفيذ منطق يعالج استثناءات الكتابة، مثل أن تكون البيانات خارج النطاقات أو حدوث خطأ في النظام الداخلي. يمكنك تطبيق استراتيجيات التراجع وإعادة المحاولة على آلية جدولة المهام. إذا لم تنجح عملية الكتابة في Health Connect في النهاية، تأكَّد من أنّ تطبيقك يمكنه تجاوز نقطة التصدير هذه. لا تنسَ تسجيل الأخطاء والإبلاغ عنها للمساعدة في تشخيصها.
عند تتبُّع البيانات، هناك بعض الاقتراحات التي يمكنك اتّباعها حسب الطريقة التي يكتب بها تطبيقك البيانات.
التعامل مع المناطق الزمنية
عند كتابة سجلات تستند إلى الوقت، تجنَّب ضبط الإزاحات على zoneOffset.UTC
تلقائيًا لأنّ ذلك قد يؤدي إلى طوابع زمنية غير دقيقة عندما يكون المستخدمون في
مناطق أخرى. بدلاً من ذلك، احسب الإزاحة استنادًا إلى الموقع الجغرافي الفعلي للجهاز. يمكنك استرداد المنطقة الزمنية للجهاز باستخدام
ZoneId.systemDefault().
val endTime = Instant.now() val startTime = endTime.minus(Duration.ofDays(1)) val stepsRecords = mutableListOf<StepsRecord>() var sampleTime = startTime val minutesBetweenSamples = 15L while (sampleTime < endTime) { // Get the default ZoneId then convert it to an offset val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(sampleTime) stepsRecords += StepsRecord( startTime = sampleTime.minus(Duration.ofMinutes(minutesBetweenSamples)), startZoneOffset = zoneOffset, endTime = sampleTime, endZoneOffset = zoneOffset, count = Random.nextLong(1, 100), metadata = Metadata.activelyRecorded(device = Device(type = Device.TYPE_WATCH)), ) sampleTime = sampleTime.plus(Duration.ofMinutes(minutesBetweenSamples)) } healthConnectClient.insertRecords( stepsRecords )
لمزيد من التفاصيل، يُرجى الاطّلاع على مستندات ZoneId.
كتابة معدّل التكرار ودرجة الدقة
عند كتابة البيانات في Health Connect، استخدِم دقة مناسبة. يساعد استخدام الدقة المناسبة في تقليل عبء التخزين، مع الحفاظ على بيانات متسقة ودقيقة. يشمل تحليل البيانات أمرين:
- معدّل تكرار عمليات الكتابة: يحدّد عدد المرّات التي يكتب فيها تطبيقك أي بيانات جديدة في Health Connect.
- اكتب البيانات بأسرع ما يمكن عند توفّر بيانات جديدة، مع مراعاة أداء الجهاز.
- لتجنُّب التأثير سلبًا في عمر البطارية والجوانب الأخرى المتعلّقة بالأداء، يجب ألا تقلّ المدة الفاصلة بين عمليات الكتابة عن 15 دقيقة.
- درجة دقة البيانات المكتوبة: معدّل أخذ عيّنات من البيانات.
- على سبيل المثال، كتابة عيّنات معدّل نبضات القلب كل 5 ثوانٍ
- لا يتطلّب كل نوع من البيانات معدّل أخذ العيّنات نفسه. لا فائدة تُذكر من تعديل بيانات عدد الخطوات كل ثانية، مقارنةً بمدّة أقل تكرارًا، مثل كل 60 ثانية.
- قد تتيح معدّلات العيّنات الأعلى للمستخدمين الاطّلاع على بيانات الصحة واللياقة البدنية بشكل أكثر تفصيلاً ودقّة. يجب أن تحقق معدلات تكرار أخذ العينات توازنًا بين التفاصيل والأداء.
إرشادات إضافية
اتّبِع الإرشادات التالية عند كتابة البيانات:
- في كل عملية مزامنة، لا تكتب سوى البيانات الجديدة والبيانات المعدَّلة منذ آخر عملية مزامنة.
- قسِّم الطلبات إلى أجزاء لا تتجاوز 1,000 سجلّ لكل طلب كتابة.
- حصر تنفيذ المهام عندما يكون الجهاز غير نشط ومستوى شحن البطارية ليس منخفضًا
- بالنسبة إلى المهام التي يتم تنفيذها في الخلفية، استخدِم WorkManager لجدولة المهام الدورية، مع فترة زمنية قصوى تبلغ 15 دقيقة.
يستخدم الرمز التالي WorkManager لجدولة مهام دورية تعمل في الخلفية، مع فترة زمنية قصوى تبلغ 15 دقيقة وفاصل زمني مرن يبلغ 5 دقائق. يتم ضبط هذا الإعداد باستخدام فئة PeriodicWorkRequest.Builder.
val constraints = Constraints.Builder()
.requiresBatteryNotLow()
.requiresDeviceIdle(true)
.build()
val writeDataWork = PeriodicWorkRequestBuilder<WriteDataToHealthConnectWorker>(
15,
TimeUnit.MINUTES,
5,
TimeUnit.MINUTES
)
.setConstraints(constraints)
.build()
التتبُّع النشط
ويشمل ذلك التطبيقات التي تتتبّع البيانات المستندة إلى الأحداث، مثل التمارين والنوم، أو بيانات أدخلها المستخدم يدويًا، مثل التغذية. يتم إنشاء هذه السجلات عندما يكون التطبيق في المقدّمة، أو في أحداث نادرة يتم فيها استخدام التطبيق بضع مرات في اليوم.
تأكَّد من أنّ تطبيقك لا يبقي Health Connect قيد التشغيل طوال مدة الحدث.
يجب كتابة البيانات في Health Connect بإحدى الطريقتَين التاليتَين:
- مزامنة البيانات مع Health Connect بعد اكتمال الحدث على سبيل المثال، تتم مزامنة البيانات عندما ينهي المستخدم جلسة تمرين يتم تتبُّعها.
- جدولة مهمة لمرة واحدة باستخدام
WorkManagerلمزامنة البيانات في وقت لاحق
أفضل الممارسات المتعلّقة بدقة الكتابة وعدد مرّاتها
عند كتابة البيانات في Health Connect، استخدِم دقة مناسبة. يساعد استخدام الدقة المناسبة في تقليل عبء التخزين، مع الحفاظ على بيانات متسقة ودقيقة. يشمل تحليل البيانات أمرين:
معدّل تكرار عمليات الكتابة: عدد المرات التي يرسل فيها تطبيقك أي بيانات جديدة إلى Health Connect اكتب البيانات بأسرع ما يمكن عند توفّر بيانات جديدة، مع مراعاة أداء الجهاز. لتجنُّب التأثير سلبًا في عمر البطارية وجوانب الأداء الأخرى، يجب أن يكون الحد الأقصى للفاصل الزمني بين عمليات الكتابة 15 دقيقة.
دقة البيانات المكتوبة: عدد المرات التي تم فيها أخذ عيّنات من البيانات التي تم إرسالها. على سبيل المثال، كتابة عيّنات معدّل نبضات القلب كل 5 ثوانٍ. لا يتطلّب كل نوع من البيانات معدّل أخذ عيّنات مماثلاً. لا فائدة تُذكر من تعديل بيانات عدد الخطوات كل ثانية، مقارنةً بمعدّل أقل تكرارًا، مثل كل 60 ثانية. ومع ذلك، قد تتيح معدّلات أخذ العيّنات الأعلى للمستخدمين الاطّلاع على بيانات الصحة واللياقة البدنية بشكل أكثر تفصيلاً ودقة. يجب أن تحقق معدلات أخذ العينات توازنًا بين التفاصيل والأداء.
بنية السجلات الخاصة ببيانات السلسلة
بالنسبة إلى أنواع البيانات التي تستخدم سلسلة من العيّنات، مثل HeartRateRecord، من المهم تنظيم السجلات بشكل صحيح. بدلاً من إنشاء سجلّ واحد
طويل الأمد يتم تعديله باستمرار، عليك إنشاء سجلّات متعددة أصغر حجمًا، يمثّل كل منها فاصلًا زمنيًا محددًا.
على سبيل المثال، بالنسبة إلى بيانات معدّل نبضات القلب، عليك إنشاء HeartRateRecord لكل دقيقة. سيتضمّن كل سجلّ وقت بدء ووقت انتهاء يمتدان على مدار تلك الدقيقة، وسيحتوي على جميع عيّنات معدّل نبضات القلب التي تم تسجيلها خلال تلك الدقيقة.
أثناء عمليات المزامنة المنتظمة مع Health Connect (على سبيل المثال، كل 15 دقيقة)، يجب أن يسجّل تطبيقك جميع البيانات التي تم إنشاؤها كل دقيقة منذ عملية المزامنة السابقة. يساعد ذلك في الحفاظ على حجم السجلات ضمن نطاق يمكن إدارته ويحسّن أداء طلبات البحث ومعالجة البيانات.
يوضّح المثال التالي كيفية إنشاء HeartRateRecord لمدة دقيقة واحدة، ويتضمّن عدة عيّنات:
val startTime = Instant.now().truncatedTo(ChronoUnit.MINUTES) val endTime = startTime.plus(Duration.ofMinutes(1)) val heartRateRecord = HeartRateRecord( startTime = startTime, startZoneOffset = ZoneOffset.UTC, endTime = endTime, endZoneOffset = ZoneOffset.UTC, // Create a new record every minute, containing a list of samples. samples = listOf( HeartRateRecord.Sample( time = startTime + Duration.ofSeconds(15), beatsPerMinute = 80, ), HeartRateRecord.Sample( time = startTime + Duration.ofSeconds(30), beatsPerMinute = 82, ), HeartRateRecord.Sample( time = startTime + Duration.ofSeconds(45), beatsPerMinute = 85, ) ), metadata = Metadata.activelyRecorded( device = Device(type = Device.TYPE_WATCH) ))
كتابة البيانات التي يتم تتبُّعها على مدار اليوم
بالنسبة إلى البيانات التي يتم جمعها بشكل مستمر، مثل عدد الخطوات، يجب أن يكتب تطبيقك البيانات إلى Health Connect بأسرع ما يمكن عند توفّر بيانات جديدة. لتجنُّب التأثير سلبًا في عمر البطارية وجوانب الأداء الأخرى، يجب ألا تتجاوز الفترة الفاصلة بين عمليات الكتابة 15 دقيقة.
نوع البيانات |
الوحدة |
النتيجة المتوقّعة |
مثال |
الخطوات |
الخطوات |
كل دقيقة واحدة |
23:14 - 23:15 - 5 خطوات 23:16 - 23:17 - 22 خطوة 23:17 - 23:18 - 8 خطوات |
StepsCadence |
خطوة/دقيقة |
كل دقيقة واحدة |
23:14 - 23:15 - 5 خطوات في الدقيقة 23:16 - 23:17 - 22 خطوة في الدقيقة 23:17 - 23:18 - 8 خطوة في الدقيقة |
عدد دفعات الكرسي المتحرك |
الدفعات |
كل دقيقة واحدة |
23:14 - 23:15 - 5 إشعارات 23:16 - 23:17 - 22 إشعارًا 23:17 - 23:18 - 8 إشعارات |
ActiveCaloriesBurned |
السعرات الحرارية |
كل 15 دقيقة |
23:15 - 23:30 - سعرتان حراريتان 23:30 - 23:45 - 25 سعرة حرارية 23:45 - 00:00 - 5 سعرات حرارية |
TotalCaloriesBurned |
السعرات الحرارية |
كل 15 دقيقة |
23:15 - 23:30 - 16 سعرة حرارية 23:30 - 23:45 - 16 سعرة حرارية 23:45 - 00:00 - 16 سعرة حرارية |
المسافة |
كلم/دقيقة |
كل دقيقة واحدة |
23:14-23:15 - 0.008 كلم 23:16 - 23:16 - 0.021 كم 23:17 - 23:18 - 0.012 كلم |
ElevationGained |
m |
كل دقيقة واحدة |
20:36 - 20:37 - 3.048 متر 20:39 - 20:40 - 3.048 متر 23:23 - 23:24 - 9.144 متر |
FloorsClimbed |
الطوابق |
كل دقيقة واحدة |
23:14 - 23:15 - 5 طوابق 23:16 - 23:16 - 22 طابقًا 23:17 - 23:18 - 8 طوابق |
HeartRate |
نبضة في الدقيقة |
4 مرات في الدقيقة |
6:11:15 صباحًا - 55 نبضة في الدقيقة 6:11:30 صباحًا - 56 نبضة في الدقيقة 6:11:45 صباحًا - 56 نبضة في الدقيقة 6:12:00 صباحًا - 55 نبضة في الدقيقة |
HeartRateVariabilityRmssd |
مللي ثانية |
كل دقيقة واحدة |
6:11 صباحًا - 23 ملي ثانية |
RespiratoryRate |
نفَس/دقيقة |
كل دقيقة واحدة |
23:14 - 23:15 - 60 نفَسًا في الدقيقة 23:16 - 23:16 - 62 نفَسًا في الدقيقة 23:17 - 23:18 - 64 نفَسًا في الدقيقة |
OxygenSaturation |
% |
كل ساعة واحدة |
6:11 - 95.208% |
يجب كتابة البيانات في Health Connect في نهاية جلسة التمرين أو النوم. بالنسبة إلى التتبُّع النشط، مثل التمارين الرياضية والنوم، أو بيانات أدخلها المستخدم يدويًا، مثل التغذية، يتم إنشاء هذه السجلات عندما يكون التطبيق في المقدّمة، أو في حالات نادرة يتم استخدامه فيها بضع مرات في اليوم.
تأكَّد من أنّ تطبيقك لا يبقي Health Connect قيد التشغيل طوال مدة الحدث.
يجب كتابة البيانات في Health Connect بإحدى الطريقتَين التاليتَين:
- مزامنة البيانات مع Health Connect بعد اكتمال الحدث على سبيل المثال، تتم مزامنة البيانات عندما ينهي المستخدم جلسة تمرين يتم تتبُّعها.
- جدولة مهمة لمرة واحدة باستخدام WorkManager لمزامنة البيانات لاحقًا
جلسات التمرين الرياضي والنوم
يجب أن يلتزم تطبيقك على الأقل بالإرشادات الواردة في عمود المتوقّع في الجدول 2. اتّبِع الإرشادات الواردة في عمود الأفضل حيثما أمكن ذلك.
يوضّح الجدول التالي كيفية كتابة البيانات أثناء التمرين:
نوع البيانات |
الوحدة |
النتيجة المتوقّعة |
مع أطيب التحيات |
مثال |
الخطوات |
الخطوات |
كل دقيقة واحدة |
كل ثانية واحدة |
23:14-23:15 - 5 خطوات 23:16 - 23:17 - 22 خطوة 23:17 - 23:18 - 8 خطوات |
StepsCadence |
خطوة/دقيقة |
كل دقيقة واحدة |
كل ثانية واحدة |
23:14-23:15 - 35 خطوة في الدقيقة 23:16 - 23:17 - 37 خطوة في الدقيقة 23:17 - 23:18 - 40 خطوة في الدقيقة |
عدد دفعات الكرسي المتحرك |
الدفعات |
كل دقيقة واحدة |
كل ثانية واحدة |
23:14-23:15 - 5 إشعارات 23:16 - 23:17 - 22 إشعارًا 23:17 - 23:18 - 8 إشعارات |
CyclingPedalingCadence |
rpm |
كل دقيقة واحدة |
كل ثانية واحدة |
23:14-23:15 - 65 دورة في الدقيقة 23:16 - 23:17 - 70 دورة في الدقيقة 23:17 - 23:18 - 68 دورة في الدقيقة |
الطاقة |
واط |
كل دقيقة واحدة |
كل ثانية واحدة |
23:14-23:15 - 250 واط 23:16 - 23:17 - 255 واط 23:17 - 23:18 - 245 واط |
السرعة |
كلم/دقيقة |
كل دقيقة واحدة |
كل ثانية واحدة |
23:14-23:15 - 0.3 كم/دقيقة 23:16 - 23:17 - 0.4 كم/دقيقة 23:17 - 23:18 -0.4 كم/دقيقة |
المسافة |
كلم/دقيقة |
كل دقيقة واحدة |
كل ثانية واحدة |
23:14-23:15 - 0.008 كلم 23:16 - 23:16 - 0.021 كم 23:17 - 23:18 - 0.012 كلم |
ActiveCaloriesBurned |
السعرات الحرارية |
كل دقيقة واحدة |
كل ثانية واحدة |
23:14-23:15 - 20 سعرة حرارية 23:16 - 23:17 - 20 سعرة حرارية 23:17 - 23:18 - 25 سعرة حرارية |
TotalCaloriesBurned |
السعرات الحرارية |
كل دقيقة واحدة |
كل ثانية واحدة |
23:14-23:15 - 36 سعرة حرارية 23:16 - 23:17 - 36 سعرة حرارية 23:17 - 23:18 - 41 سعرة حرارية |
ElevationGained |
m |
كل دقيقة واحدة |
كل ثانية واحدة |
20:36 - 20:37 - 3.048 متر 20:39 - 20:40 - 3.048 متر 23:23 - 23:24 - 9.144 متر |
ExerciseRoutes |
lat/lng/alt |
كل 3 إلى 5 ثوانٍ |
كل ثانية واحدة |
|
HeartRate |
نبضة في الدقيقة |
4 مرات في الدقيقة |
كل ثانية واحدة |
23:14-23:15 - 150 نبضة في الدقيقة |
يوضّح الجدول 3 كيفية كتابة البيانات أثناء جلسة نوم أو بعدها:
نوع البيانات |
الوحدة |
النماذج المتوقّعة |
مثال |
مراحل النوم |
مرحلة |
فترة زمنية تفصيلية لكل مرحلة من مراحل النوم |
23:46 - 23:50 - استيقاظ 23:50 - 23:56 - نوم خفيف 23:56 - 00:16 - نوم عميق |
RestingHeartRate |
نبضة في الدقيقة |
قيمة يومية واحدة (من المتوقّع أن تظهر في الصباح الباكر) |
6:11 صباحًا - 60 نبضة في الدقيقة |
OxygenSaturation |
% |
قيمة يومية واحدة (من المتوقّع أن تظهر في الصباح الباكر) |
6:11 - 95.208% |
فعاليات تضمّ عدّة رياضات
يستخدم هذا الأسلوب أنواع البيانات والبِنى الحالية، ويتحقّق من التوافق مع عمليات التنفيذ الحالية لقارئات البيانات وHealth Connect. هذا أسلوب شائع تتّبعه منصات اللياقة البدنية.
بالإضافة إلى ذلك، لا تكون الجلسات الفردية، مثل السباحة وركوب الدراجات والجري، مرتبطة بشكل أساسي في Health Connect، ويجب أن تستنتج أدوات قراءة البيانات العلاقة بين هذه الجلسات استنادًا إلى تقاربها الزمني. لا يتم تمثيل عمليات الانتقال بين الأنشطة، مثل الانتقال من السباحة إلى ركوب الدراجة، بشكل صريح.
يوضّح المثال التالي كيفية كتابة بيانات خاصة بسباق ثلاثي:
val swimStartTime = Instant.parse("2024-08-22T08:00:00Z") val swimEndTime = Instant.parse("2024-08-22T08:30:00Z") val bikeStartTime = Instant.parse("2024-08-22T08:40:00Z") val bikeEndTime = Instant.parse("2024-08-22T09:40:00Z") val runStartTime = Instant.parse("2024-08-22T09:50:00Z") val runEndTime = Instant.parse("2024-08-22T10:20:00Z") val swimSession = ExerciseSessionRecord( startTime = swimStartTime, endTime = swimEndTime, exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_OPEN_WATER, metadata = Metadata.activelyRecorded( device = Device(type = Device.TYPE_WATCH) ), startZoneOffset = null, endZoneOffset = null, ) val bikeSession = ExerciseSessionRecord( startTime = bikeStartTime, endTime = bikeEndTime, exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_BIKING, metadata = Metadata.activelyRecorded( device = Device(type = Device.TYPE_WATCH) ), startZoneOffset = null, endZoneOffset = null, ) val runSession = ExerciseSessionRecord( startTime = runStartTime, endTime = runEndTime, exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING, metadata = Metadata.activelyRecorded( device = Device(type = Device.TYPE_WATCH) ), startZoneOffset = null, endZoneOffset = null, ) healthConnectClient.insertRecords(listOf(swimSession, bikeSession, runSession))
التعامل مع الاستثناءات
يُصدر تطبيق Health Connect استثناءات عادية لعمليات الإنشاء والقراءة والتعديل والحذف عند حدوث مشكلة. يجب أن يرصد تطبيقك كل استثناء من هذه الاستثناءات ويتعامل معه على النحو المناسب.
تدرج كل طريقة في HealthConnectClient الاستثناءات التي يمكن طرحها.
بشكل عام، يجب أن يتعامل تطبيقك مع الاستثناءات التالية:
| استثناء | الوصف | أفضل الممارسات المقترَحة |
|---|---|---|
IllegalStateException
| حدث أحد السيناريوهات التالية:
| عليك أولاً التعامل مع المشاكل المحتملة في المدخلات قبل تقديم طلب. من الأفضل تعيين قيم للمتغيّرات أو استخدامها كمَعلمات ضمن دالة مخصّصة بدلاً من استخدامها مباشرةً في طلباتك، وذلك حتى تتمكّن من تطبيق استراتيجيات معالجة الأخطاء. |
IOException
| تحدث مشاكل عند قراءة البيانات وكتابتها من القرص. | لتجنُّب هذه المشكلة، إليك بعض الاقتراحات:
|
RemoteException
| حدثت أخطاء في الخدمة الأساسية التي يتصل بها حزمة تطوير البرامج (SDK) أو أثناء التواصل معها. على سبيل المثال، يحاول تطبيقك حذف سجلّ يتضمّن uid معيّنًا. ومع ذلك، يتم طرح الاستثناء بعد أن يكتشف التطبيق عند التحقّق من الخدمة الأساسية أنّ السجلّ غير متوفّر.
| لتجنُّب هذه المشكلة، إليك بعض الاقتراحات:
|
SecurityException
| تحدث مشاكل عندما تتطلّب الطلبات أذونات لم يتم منحها. | لتجنُّب ذلك، تأكَّد من الإفصاح عن استخدام أنواع بيانات Health Connect في تطبيقك المنشور، ويجب أيضًا الإفصاح عن أذونات Health Connect في ملف البيان وفي نشاطك. |