تطوير تجارب بيانات المؤشرات الحيوية باستخدام Health Connect

إذا كنت تتطلّع إلى إنشاء تطبيق يدير المؤشرات الحيوية للمستخدمين، يمكنك استخدام Health Connect لتنفيذ إجراءات مثل:

  • قراءة بيانات المؤشرات الحيوية، مثل ضغط الدم ومعدّل نبضات القلب ودرجة حرارة الجسم، من تطبيقات أخرى
  • كتابة بيانات المؤشرات الحيوية التي يسجّلها تطبيقك أو أجهزتك المرتبطة
  • تتبُّع المؤشرات وتقديم إحصاءات صحية استنادًا إلى بيانات العلامات الحيوية

يوضّح هذا الدليل كيفية التعامل مع أنواع بيانات المؤشرات الحيوية، ويشمل الأذونات وسير عمل القراءة والكتابة وأفضل الممارسات.

نظرة عامة: إنشاء أداة شاملة لتتبُّع المؤشرات الحيوية

يمكنك إنشاء تجربة شاملة لتتبُّع المؤشرات الحيوية باستخدام Health Connect من خلال اتّباع الخطوات الأساسية التالية:

  • طلب الأذونات المناسبة لأنواع بيانات المؤشرات الحيوية
  • كتابة بيانات المؤشرات الحيوية باستخدام سجلات مثل BloodPressureRecord وHeartRateRecord وسجلات المؤشرات الحيوية الأخرى
  • قراءة بيانات المؤشرات الحيوية لعرضها أو تحليلها أو مزامنتها
  • استخدام التجميع لكتابة البيانات وقراءتها بكفاءة

تتيح سير العمل هذا إمكانية التشغيل التفاعلي مع تطبيقات Health Connect الأخرى، كما تتحقّق من إذن الوصول إلى البيانات الذي يتحكّم فيه المستخدم.

قبل البدء

قبل تنفيذ ميزات "المؤشرات الحيوية":

المفاهيم الرئيسية

يتم تمثيل بيانات المؤشرات الحيوية في Health Connect بأنواع مختلفة من السجلات، وكل نوع يتوافق مع قياس فسيولوجي محدّد. على عكس جلسات التمرين، يتم غالبًا تسجيل المؤشرات الحيوية كبيانات تستند إلى نقطة زمنية أو فاصل زمني.

أنواع بيانات المؤشرات الحيوية

يتم تمثيل بيانات المؤشرات الحيوية من خلال أنواع سجلات فردية، وتشمل الأنواع الشائعة ما يلي:

  • BloodPressureRecord: تمثّل هذه السمة قراءة واحدة لضغط الدم، بما في ذلك ضغط الدم الانقباضي والانبساطي ووضعية الجسم.
  • HeartRateRecord: يمثّل سلسلة من قياسات معدّل نبضات القلب.
  • RestingHeartRateRecord: يمثّل هذا النوع قياسًا واحدًا لمعدّل نبض القلب أثناء الراحة.
  • BodyTemperatureRecord: يمثّل هذا النوع قراءة واحدة لدرجة حرارة الجسم، بما في ذلك موقع القياس.
  • BloodGlucoseRecord: يمثّل هذا النوع قراءة واحدة لمستوى الغلوكوز في الدم، بما في ذلك العلاقة بالوجبة ومصدر العيّنة.
  • OxygenSaturationRecord: يمثّل هذا النوع قراءة واحدة لنسبة الأكسجين في الدم.
  • RespiratoryRateRecord: يمثّل قياسًا واحدًا لمعدّل التنفّس.

للحصول على قائمة كاملة بأنواع البيانات، راجِع أنواع بيانات Health Connect.

اعتبارات التطوير

يمكن أن تكون بيانات المؤشرات الحيوية حسّاسة، وقد تحتاج التطبيقات إلى كتابة البيانات استجابةً للقياسات من أجهزة الاستشعار أو بيانات أدخلها المستخدم، أو مزامنة البيانات من الخلفية. وتُعد الأذونات ضرورية للتعامل مع بيانات المؤشرات الحيوية.

الأذونات

يجب أن يطلب تطبيقك أذونات Health Connect ذات الصلة قبل قراءة بيانات المؤشرات الحيوية أو تعديلها. تشمل الأذونات الشائعة للمؤشرات الحيوية ضغط الدم ومعدّل نبضات القلب ودرجة حرارة الجسم ومستوى الغلوكوز في الدم وتشبّع الأكسجين في الدم ومعدّل التنفس. ويتضمن ذلك ما يلي:

  • ضغط الدم: أذونات القراءة والكتابة لـ BloodPressureRecord
  • معدّل نبضات القلب: أذونات القراءة والكتابة في HeartRateRecord
  • معدّل النبض أثناء الراحة: أذونات القراءة والكتابة في RestingHeartRateRecord
  • درجة حرارة الجسم: أذونات القراءة والكتابة في BodyTemperatureRecord
  • الغلوكوز في الدم: أذونات القراءة والكتابة لبيانات BloodGlucoseRecord
  • تشبّع الأكسجين: أذونات القراءة والكتابة لبيانات OxygenSaturationRecord
  • معدّل التنفّس: أذونات القراءة والكتابة لبيانات RespiratoryRateRecord

يوضّح المثال التالي كيفية طلب أذونات الوصول إلى بيانات ضغط الدم ومعدّل نبضات القلب ودرجة حرارة الجسم:

بعد إنشاء مثيل للعميل، يجب أن يطلب تطبيقك أذونات من المستخدم. يجب السماح للمستخدمين بمنح الأذونات أو رفضها في أي وقت. لإجراء ذلك، أنشئ مجموعة من الأذونات لأنواع البيانات المطلوبة. تأكَّد من أنّ الأذونات في المجموعة معرَّفة في ملف بيان Android أولاً.

val permissions =
    setOf(
        HealthPermission.getReadPermission(BloodPressureRecord::class),
        HealthPermission.getWritePermission(BloodPressureRecord::class),
        HealthPermission.getReadPermission(HeartRateRecord::class),
        HealthPermission.getWritePermission(HeartRateRecord::class),
        HealthPermission.getReadPermission(BodyTemperatureRecord::class),
        HealthPermission.getWritePermission(BodyTemperatureRecord::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.") }
    }
}
بما أنّ المستخدمين يمكنهم منح الأذونات أو إبطالها في أي وقت، يجب أن يتحقّق تطبيقك من الأذونات في كل مرة قبل استخدامها، وأن يتعامل مع الحالات التي يتم فيها فقدان الإذن.

لطلب الأذونات، استدعِ الدالة checkPermissionsAndRun:

if (!granted.containsAll(permissions)) {
    // Check if required permissions are not granted, and return
    return emptySet()
}
// Permissions already granted; proceed with inserting or reading data

إذا كنت بحاجة إلى طلب أذونات لنوع بيانات واحد فقط، مثل ضغط الدم، عليك تضمين نوع البيانات هذا فقط في مجموعة الأذونات:

يتم حماية إمكانية الوصول إلى بيانات ضغط الدم من خلال الأذونات التالية:

  • android.permission.health.READ_BLOOD_PRESSURE
  • android.permission.health.WRITE_BLOOD_PRESSURE

لإضافة إمكانية قياس ضغط الدم إلى تطبيقك، ابدأ بطلب أذونات لنوع البيانات BloodPressureRecord.

في ما يلي الإذن الذي يجب الإفصاح عنه لتتمكّن من تسجيل بيانات ضغط الدم:

<application>
  <uses-permission
android:name="android.permission.health.WRITE_BLOOD_PRESSURE" />
...
</application>

لقراءة ضغط الدم، يجب طلب الأذونات التالية:

<application>
  <uses-permission
android:name="android.permission.health.READ_BLOOD_PRESSURE" />
...
</application>

كتابة بيانات المؤشرات الحيوية

يوضّح هذا القسم كيفية كتابة بيانات المؤشرات الحيوية في Health Connect. عادةً ما يتم تسجيل بيانات المؤشرات الحيوية كسجلات فردية. إذا كنت تكتب سجلات متعددة في المرة الواحدة، مثل المزامنة من جهاز استشعار أو خادم خلفي، استخدِم التجميع.

مثال على كتابة BloodPressureRecord:

suspend fun writeBloodPressureRecord(healthConnectClient: HealthConnectClient) {
    val record = BloodPressureRecord(
        time = Instant.now(),
        zoneOffset = ZoneOffset.UTC,
        systolic = Pressure.millimetersOfMercury(120.0),
        diastolic = Pressure.millimetersOfMercury(80.0),
        bodyPosition = BloodPressureRecord.BODY_POSITION_SITTING_DOWN,
        measurementLocation = BloodPressureRecord.MEASUREMENT_LOCATION_LEFT_WRIST
    )
    healthConnectClient.insertRecords(listOf(record))
}

الكتابة المجمّعة

إذا كان تطبيقك بحاجة إلى كتابة نقاط بيانات متعددة، مثل مزامنة البيانات من جهاز متصل أو خدمة خلفية، عليك تجميع عمليات الكتابة لتحسين الكفاءة وتقليل استهلاك البطارية، إذ يمكن لتطبيق Health Connect التعامل مع ما يصل إلى 1,000 سجلّ في طلب كتابة واحد.

يوضّح الرمز التالي كيفية كتابة سجلّات متعددة دفعة واحدة:

suspend fun writeBatchRecords(healthConnectClient: HealthConnectClient) {
    val bloodPressureRecord = BloodPressureRecord(
        time = Instant.now(),
        zoneOffset = ZoneOffset.UTC,
        systolic = Pressure.millimetersOfMercury(120.0),
        diastolic = Pressure.millimetersOfMercury(80.0),
        bodyPosition = BloodPressureRecord.BODY_POSITION_SITTING_DOWN,
        measurementLocation = BloodPressureRecord.MEASUREMENT_LOCATION_LEFT_WRIST
    )
    val heartRateRecord = HeartRateRecord(
        startTime = Instant.now().minusSeconds(60),
        startZoneOffset = ZoneOffset.UTC,
        endTime = Instant.now(),
        endZoneOffset = ZoneOffset.UTC,
        samples = listOf(HeartRateRecord.Sample(time = Instant.now().minusSeconds(30), beatsPerMinute = 80))
    )
    healthConnectClient.insertRecords(listOf(bloodPressureRecord, heartRateRecord))
}

قراءة بيانات المؤشرات الحيوية

يمكن للتطبيقات قراءة بيانات المؤشرات الحيوية لعرض القياسات أو تحليل المؤشرات أو مزامنة البيانات مع خادم خارجي. لقراءة المؤشرات الحيوية، استخدِم ReadRecordsRequest مع نوع السجلّ المحدّد وفلتر حسب النطاق الزمني.

مثال على قراءة بيانات BloodPressureRecord:

suspend fun readBloodPressureRecords(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    val response = healthConnectClient.readRecords(
        ReadRecordsRequest(
            recordType = BloodPressureRecord::class,
            timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
        )
    )

    for (record in response.records) {
        // Process each blood pressure record
        val systolic = record.systolic
        val diastolic = record.diastolic
    }
}

إذا كنت بحاجة إلى مزامنة بيانات المؤشرات الحيوية مع خادم خلفي أو إبقاء مستودع بيانات تطبيقك محدّثًا مع Health Connect، استخدِم ChangeLogs. يتيح لك ذلك استرداد قائمة بالسجلات التي تم إدراجها أو تعديلها أو حذفها منذ وقت معيّن، ما يجعله أكثر فعالية من تتبُّع التغييرات يدويًا أو قراءة جميع البيانات بشكل متكرّر. لمزيد من المعلومات، اطّلِع على مزامنة البيانات مع Health Connect.

أفضل الممارسات

اتّبِع الإرشادات التالية لتحسين موثوقية البيانات وتجربة المستخدم:

  • طلبات الكتابة المجمّعة: لتقليل الحمل الزائد للإدخال/الإخراج والحفاظ على عمر البطارية، يمكنك تجميع نقاط البيانات في طلب insertRecords واحد مع مجموعات تصل إلى 1,000 سجلّ، بدلاً من كتابة كل نقطة على حدة.
  • الكتابة بشكل متكرّر أثناء التتبُّع المباشر: للحصول على تحديثات متكرّرة من أجهزة الاستشعار (مثل أجهزة مراقبة الغلوكوز المستمرة أو أجهزة مراقبة معدّل نبضات القلب)، اكتب البيانات على دفعات بفواصل زمنية تصل إلى 15 دقيقة لتحقيق التوازن بين التحديثات في الوقت الفعلي وكفاءة البطارية.
  • استخدام WorkManager لعمليات المزامنة في الخلفية: استخدِم WorkManager لعمليات الكتابة المؤجّلة، مثل مزامنة البيانات من جهاز مصاحب أو خدمة خلفية. احرص على أن يكون الفاصل الزمني بين عمليات الكتابة المجمّعة 15 دقيقة.
  • تجنُّب كتابة بيانات مكرّرة: استخدام معرّفات العملاء: عند إنشاء سجلّات، اضبط metadata.clientRecordId. يستخدم Health Connect هذا المعرّف لتحديد السجلّات الفريدة. إذا حاولت كتابة سجلّ يتضمّن clientRecordId سبق أن تم استخدامه، سيتجاهل Health Connect السجلّ المكرّر أو يعدّل السجلّ الحالي بدلاً من إنشاء سجلّ جديد. ويُعدّ ضبط metadata.clientRecordId الطريقة الأكثر فعالية لمنع تكرار السجلّات أثناء عمليات إعادة محاولة المزامنة أو إعادة تثبيت التطبيق.
    val record = StepsRecord(
        count = 100,
        startTime = startTime,
        endTime = endTime,
        startZoneOffset = ZoneOffset.UTC,
        endZoneOffset = ZoneOffset.UTC,
        metadata = Metadata(
            // Use a unique ID from your own database
            clientRecordId = "daily_steps_2023_10_27_user_123"
        )
    )
  • التحقّق من البيانات الحالية: قبل مزامنة البيانات، أرسِل طلب بحث إلى Health Connect عن السجلات ضمن النطاق الزمني للمزامنة لمعرفة ما إذا كانت بيانات تطبيقك متوفّرة من قبل، وذلك لتجنُّب تكرار البيانات أو الكتابة فوق البيانات الأحدث.
  • تقديم أسباب واضحة للحصول على الإذن: استخدِم مسار Permission.createIntent لتوضيح سبب حاجة تطبيقك إلى الوصول إلى البيانات الصحية، على سبيل المثال: "لمراقبة مؤشرات ضغط الدم وتقديم إحصاءات".
  • مواءمة الطوابع الزمنية مع القياسات: تأكَّد من أنّ الطوابع الزمنية للسجلات تعكس بدقة وقت إجراء القياسات. بالنسبة إلى البيانات الفاصلة مثل HeartRateRecord، تأكَّد من صحة startTime وendTime.

الاختبار

للتحقّق من صحة البيانات وتوفير تجربة عالية الجودة للمستخدم، اتّبِع استراتيجيات الاختبار التالية وراجِع مستند أهم حالات الاستخدام للاختبار الرسمي.

أدوات التحقّق

  • مجموعة أدوات Health Connect: استخدِم هذا التطبيق المصاحب لفحص السجلات يدويًا وحذف بيانات الاختبار ومحاكاة التغييرات في قاعدة البيانات. هذه هي أفضل طريقة للتأكّد من تخزين السجلات بشكل صحيح.
  • اختبار الوحدات باستخدام FakeHealthConnectClient: استخدِم مكتبة الاختبار للتحقّق من طريقة تعامل تطبيقك مع الحالات الحدّية، مثل إلغاء الإذن أو استثناءات واجهة برمجة التطبيقات، بدون الحاجة إلى جهاز فعلي.

قائمة التحقّق من الجودة

البنية النموذجية

يتضمّن تنفيذ المؤشرات الحيوية عادةً ما يلي:

المكوّن يدير
عنصر التحكّم في "المؤشرات الحيوية" قراءة المستشعر/الإدخال
منطق تجميع البيانات
طبقة المستودع (تتضمّن عمليات Health Connect): إدراج سجلّات المؤشرات الحيوية
قراءة سجلّات المؤشرات الحيوية
طبقة واجهة المستخدم (شاشات العرض): القراءات المباشرة
البيانات السابقة
الرسومات البيانية والمؤشرات

تحديد المشاكل وحلّها

المشكلة السبب المحتمل درجة الدقة
أنواع البيانات غير المتوفّرة (مثل ضغط الدم) عدم توفّر أذونات الكتابة أو فلاتر الوقت غير صحيحة تأكَّد من أنّك طلبت إذن الوصول إلى نوع البيانات المحدّد وأنّ المستخدم منحك هذا الإذن. تأكَّد من أنّ ReadRecordsRequest يستخدم TimeRangeFilter يغطّي وقت القياس. اطّلِع على الأذونات.
تظهر السجلات المكررة السمة clientRecordId غير متوفّرة. عيِّن clientRecordId فريدًا في Metadata لكل سجلّ. يتيح ذلك لتطبيق Health Connect إزالة التكرار إذا تمت كتابة البيانات نفسها مرتين أثناء إعادة محاولة المزامنة. اطّلِع على أفضل الممارسات.
تعذّر كتابة السجلات وحدات أو قيم غير صحيحة خارج النطاق الصالح يتحقّق Health Connect من قيم السجلات. على سبيل المثال، يجب أن تكون قيم ضغط الدم ضمن نطاق مقبول من الناحية الفسيولوجية. راجِع مستندات نوع البيانات لمعرفة النطاقات والوحدات الصالحة.

خطوات تصحيح الأخطاء الشائعة

التحقّق من حالة الإذن يجب دائمًا طلب الإذن باستخدام getPermissionStatus() قبل محاولة إجراء عملية قراءة أو كتابة، إذ يمكن للمستخدمين إلغاء الأذونات في إعدادات النظام في أي وقت.