يتوافق هذا الدليل مع الإصدار 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( device = Device(type = Device.TYPE_WATCH), recordingMethod = Metadata.RECORDING_METHOD_AUTOMATICALLY_RECORDED ) ) 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( 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( 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( device = Device(type = Device.TYPE_WATCH), recordingMethod = Metadata.RECORDING_METHOD_AUTOMATICALLY_RECORDED ) ) 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 } }
إجراء عملية إدراج أو تعديل من خلال معرّف سجلّ العميل
في حال استخدام قيمتَي Client Record ID وClient Record Version الاختياريتَين،
ننصحك باستخدام 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( clientRecordId = "Your client record ID", 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 ))
التحقّق من القيمة في "إصدار سجلّ العميل"
إذا كانت عملية إدراج البيانات أو تعديلها تتضمّن إصدار سجلّ العميل، يجري تطبيق 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( 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"
يُعدّ ضبط بيانات التعريف بشكل صحيح أمرًا بالغ الأهمية لضمان شفافية البيانات، ويساعد المستخدمين في معرفة مصدر معلوماتهم الصحية. للاطّلاع على التفاصيل الكاملة، يُرجى الرجوع إلى دليل بيانات 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(), ) 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( 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( device = Device(type = Device.TYPE_WATCH) ), startZoneOffset = null, endZoneOffset = null, ) val bikeSession = ExerciseSessionRecord( startTime = bikeStartTime, endTime = bikeEndTime, exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_BIKING, metadata = Metadata( device = Device(type = Device.TYPE_WATCH) ), startZoneOffset = null, endZoneOffset = null, ) val runSession = ExerciseSessionRecord( startTime = runStartTime, endTime = runEndTime, exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING, metadata = Metadata( device = Device(type = Device.TYPE_WATCH) ), startZoneOffset = null, endZoneOffset = null, ) healthConnectClient.insertRecords(listOf(swimSession, bikeSession, runSession))
التعامل مع الاستثناءات
يُصدر Health Connect استثناءات عادية لعمليات CRUD عند مواجهة مشكلة. يجب أن يرصد تطبيقك كل استثناء من هذه الاستثناءات ويتعامل معه على النحو المناسب.
تسرد كل طريقة في HealthConnectClient الاستثناءات التي يمكن طرحها.
وبشكل عام، يجب أن يتعامل تطبيقك مع الاستثناءات التالية:
| الاستثناء | الوصف | أفضل الممارسات المقترَحة |
|---|---|---|
IllegalStateException
| حدث أحد السيناريوهات التالية:
| عليك معالجة المشاكل المحتملة في المدخلات أولاً قبل إرسال الطلب. من الأفضل تعيين قيم للمتغيّرات أو استخدامها كمَعلمات ضمن دالة مخصّصة بدلاً من استخدامها مباشرةً في طلباتك، وذلك حتى تتمكّن من تطبيق استراتيجيات معالجة الأخطاء. |
IOException
| حدثت مشاكل عند قراءة البيانات وكتابتها من القرص. | لتجنُّب هذه المشكلة، إليك بعض الاقتراحات:
|
RemoteException
| حدثت أخطاء في الخدمة الأساسية التي يرتبط بها حزمة تطوير البرامج (SDK) أو في التواصل معها. على سبيل المثال، يحاول تطبيقك حذف سجلّ باستخدام uid معيّن، ولكن يتم طرح الاستثناء
بعد أن يكتشف التطبيق عند التحقّق من الخدمة الأساسية أنّ السجلّ غير متوفّر.
| لتجنُّب هذه المشكلة، إليك بعض الاقتراحات:
|
SecurityException
| حدثت مشاكل عندما تتطلّب الطلبات أذونات لم يتم منحها. | لتجنُّب ذلك، تأكَّد من الإفصاح عن استخدام أنواع بيانات Health Connect في تطبيقك المنشور، ويجب أيضًا الإفصاح عن أذونات Health Connect في ملف البيان وفي نشاطك. |