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

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

  • كتابة بيانات جلسات التمارين الرياضية
  • كتابة مسارات التمارين
  • كتابة مقاييس التمارين الرياضية، مثل معدّل نبضات القلب والسرعة والمسافة
  • قراءة بيانات التمارين الرياضية من تطبيقات أخرى

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

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

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

  • تنفيذ الأذونات بشكل صحيح استنادًا إلى "أذونات الصحة"
  • تسجيل الجلسات باستخدام ExerciseSessionRecord
  • تسجيل بيانات التمرين بشكل متّسق أثناء الجلسة
  • إدارة التنفيذ في الخلفية بشكلٍ سليم للتحقّق من تسجيل البيانات بشكلٍ مستمر
  • قراءة بيانات جلسة القراءة للحصول على ملخّصات وتحليلات ما بعد التمرين

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

قبل البدء

قبل تنفيذ ميزات التمارين الرياضية، يجب مراعاة ما يلي:

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

يمثّل تطبيق Health Connect بيانات التمرين باستخدام بعض المكوّنات الأساسية. يمثّل ExerciseSessionRecord السجلّ المركزي للتمرين الرياضي، ويحتوي على تفاصيل، مثل أوقات البدء أو الانتهاء ونوع التمرين. أثناء الجلسة، يمكن تسجيل أنواع مختلفة من البيانات، مثل HeartRateRecord أو SpeedRecord. بالنسبة إلى الأنشطة الخارجية، يخزّن تطبيق ExerciseRoute بيانات نظام تحديد المواقع العالمي (GPS) المرتبطة بالجلسة المعنية.

جلسات التمارين الرياضية

ExerciseSessionRecord هو السجلّ المركزي لبيانات التمارين الرياضية، ويمثّل جلسة تمارين رياضية واحدة. يخزّن كل سجلّ ما يلي:

  • startTime
  • endTime
  • exerciseType
  • البيانات الوصفية الاختيارية للجلسة (العنوان والملاحظات)

يمكن أن يحتوي ExerciseSessionRecord أيضًا على مسارات تمارين رياضية ولفات وأجزاء كجزء من بياناته. بالإضافة إلى ذلك، يمكن تسجيل أنواع بيانات أخرى، مثل HeartRateRecord أو SpeedRecord، أثناء الجلسة وربطها بها.

أنواع البيانات المرتبطة

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

  • HeartRateRecord: يمثّل سلسلة من قياسات معدّل نبضات القلب.
  • SpeedRecord: يمثّل سلسلة من قياسات السرعة.
  • DistanceRecord: تمثّل المسافة المقطوعة بين القراءات.
  • TotalCaloriesBurnedRecord: يمثّل إجمالي السعرات الحرارية المحروقة بين القراءات.
  • ElevationGainedRecord: يمثّل الارتفاع التراكمي المكتسَب بين القراءات.
  • StepsCadenceRecord: تمثّل إيقاع خطوات السير بين القراءات.
  • PowerRecord: يمثّل هذا النوع معدّل إنتاج الطاقة بين القراءات، وهو شائع في الأنشطة مثل ركوب الدراجات.

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

مسارات التمارين الرياضية

يمكنك ربط مسار بالتمارين الرياضية في الهواء الطلق باستخدام ExerciseRoute. تتألف المسارات من كائنات ExerciseRoute.Location متسلسلة يحتوي كل منها على ما يلي:

  • خط العرض وخط الطول
  • الارتفاع الاختياري
  • السمت الاختياري
  • معلومات الدقة
  • الطابع الزمني

ربط مسارات الجلسات

يحتوي ExerciseRoute على بيانات الموقع الجغرافي التسلسلية لجلسة تمرين. ولا يتم التعامل معه كسجلّ مستقل في Health Connect. بدلاً من ذلك، يمكنك تقديم بيانات ExerciseRoute عند إدراج أو تعديل ExerciseSessionRecord.

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

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

التنفيذ في الخلفية

تعمل تطبيقات التمارين الرياضية عادةً مع إيقاف تشغيل الشاشة. وعندما تكون في هذه الحالة، عليك استخدام:

  • الخدمات التي تعمل في المقدّمة لجمع بيانات الموقع الجغرافي وبيانات أجهزة الاستشعار
  • WorkManager للكتابة المؤجّلة أو المزامنة
  • استراتيجيات التجميع لكتابة السجلات العادية

الحفاظ على الاستمرارية من خلال إبقاء معرّف الجلسة متسقًا في جميع عمليات الكتابة

الأذونات

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

  • جلسات التمارين الرياضية: أذونات القراءة والكتابة في ExerciseSessionRecord
  • مسارات التمارين الرياضية: أذونات القراءة والكتابة في ExerciseRoute
  • معدّل نبضات القلب: أذونات القراءة والكتابة لبيانات HeartRateRecord.
  • السرعة: أذونات القراءة والكتابة في SpeedRecord
  • المسافة: أذونات القراءة والكتابة لـ DistanceRecord
  • السعرات الحرارية: أذونات القراءة والكتابة لبيانات TotalCaloriesBurnedRecord
  • الارتفاع التراكمي المكتسَب: أذونات القراءة والكتابة في ElevationGainedRecord
  • إيقاع خطوات السير: أذونات القراءة والكتابة لبيانات StepsCadenceRecord.
  • الطاقة: أذونات القراءة والكتابة في PowerRecord
  • الخطوات: أذونات القراءة والكتابة لـ StepsRecord

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

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

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

لطلب الأذونات، استدعِ الدالة 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_HEART_RATE
  • android.permission.health.WRITE_HEART_RATE

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

في ما يلي الإذن الذي يجب الإفصاح عنه لتتمكّن من كتابة بيانات معدّل ضربات القلب:

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

لقراءة معدّل نبضات القلب، عليك طلب الأذونات التالية:

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

تنفيذ جلسة تمرين

يوضّح هذا القسم سير العمل المقترَح لتسجيل بيانات التمرين.

بدء الجلسة

لإنشاء تمرين جديد، اتّبِع الخطوات التالية:

  1. إنشاء معرّف جلسة فريد: تأكَّد من أنّ هذا المعرّف ثابت. وفي حال تم إيقاف عملية تطبيقك وإعادة تشغيلها، يجب أن تتمكّن من استئناف استخدام المعرّف نفسه لتجنُّب الجلسات المجزّأة.
  2. اضبط قيمة metadata.clientRecordId لمنع تكرار البيانات أثناء إعادة محاولات المزامنة.
  3. اكتب ExerciseSessionRecord: أدرِج وقت البدء.
  4. ابدأ جمع بيانات نوع البيانات وبيانات نظام تحديد المواقع العالمي (GPS): لا تبدأ في جمع هذه البيانات إلا بعد تهيئة سجلّ الجلسة بنجاح.

مثال:

val sessionClientId = UUID.randomUUID().toString()
val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(startTime)

val session =   ExerciseSessionRecord(
    startTime = startTime,
    startZoneOffset = zoneOffset,
    endTime = startTime.plusSeconds(3600),
    endZoneOffset = zoneOffset,
    exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
    metadata = Metadata(clientRecordId = sessionClientId),
)

healthConnectClient.insertRecords(listOf(session))

تسجيل مسارات التمارين الرياضية

لمزيد من المعلومات حول إرشادات القراءة، اطّلِع على قراءة البيانات الأولية.

عند تسجيل مسار تمرين، يجب تجميع بياناتك. وهذا يعني أنّه بدلاً من حفظ كل نقطة GPS على حدة عند حدوثها، يمكنك جمع مجموعة من النقاط وحفظها كلها في وقت واحد في طلب واحد.

وهذا مهم لأنّه في كل مرة يقرأ فيها تطبيقك البيانات من Health Connect أو يكتبها فيه، يستهلك جزءًا صغيرًا من طاقة البطارية وقوة المعالجة.

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

// 1. Create a list to hold your route locations
val routeLocations = mutableListOf<ExerciseRoute.Location>()

// 2. Add points to your list as the exercise happens
routeLocations.add(
    ExerciseRoute.Location(
        time = Instant.now(),
        latitude = 37.7749,
        longitude = -122.4194
    )
)

// ... keep adding points over a period of time ...

// 3. Save the whole list at once (Batching)
val session = ExerciseSessionRecord(
    startTime = startTime,
    endTime = endTime,
    exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
    // We pass the whole list here
    exerciseRoute = ExerciseRoute(routeLocations)
)

healthConnectClient.insertRecords(listOf(session))

إنهاء جلسة

بعد إيقاف عملية جمع البيانات:

  • تعديل السجلّ: يرسل تطبيقك إلى ExerciseSessionRecord endTime.
  • وضع اللمسات الأخيرة على البيانات: يمكنك اختياريًا احتساب قيم الملخّص (مثل إجمالي المسافة أو متوسط السرعة) وكتابتها كسجلات إضافية.
val finishedSession = session.copy(endTime = Instant.now())
healthConnectClient.updateRecords(listOf(finishedSession))

قراءة بيانات التمارين

يمكن للتطبيقات قراءة جلسات التمارين الرياضية والبيانات المرتبطة بها لتلخيص النشاط أو تقديم إحصاءات صحية أو مزامنة البيانات مع خادم خارجي. على سبيل المثال، يمكنك قراءة ExerciseSessionRecord ثم طلب البحث عن HeartRateRecord أو DistanceRecord اللذين حدثا خلال الفترة الزمنية نفسها.

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

قراءة الجلسات

لقراءة جلسات التمارين، استخدِم ReadRecordsRequest مع ExerciseSessionRecord كنوع. عادةً ما يتم فلترة هذه البيانات حسب نطاق زمني محدّد.

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

    for (exerciseRecord in response.records) {
        // Process each session
        val exerciseType = exerciseRecord.exerciseType
        val notes = exerciseRecord.notes
    }
}

قراءة المسارات

على الرغم من أنّه يتم تسجيل بيانات ExerciseRoute كجزء من جلسة تمرين، يجب قراءتها بشكل منفصل. استخدِم طريقة getExerciseRoute() مع معرّف الجلسة لقراءة بيانات المسار:

suspend fun readExerciseRoute(
    healthConnectClient: HealthConnectClient,
    exerciseSessionRecord: ExerciseSessionRecord
) {
    // Check if the session has a route
    val route = healthConnectClient.getExerciseRoute(
        exerciseSessionRecordId = exerciseSessionRecord.metadata.id
    )

    when (route) {
        is ExerciseRouteResponse.Success -> {
            val locations = route.exerciseRoute.locations
            for (location in locations) {
                // Use latitude, longitude, and altitude
            }
        }
        is ExerciseRouteResponse.NoData -> {
            // Handle case where no route exists
        }
        is ExerciseRouteResponse.ConsentRequired -> {
            // Handle case where permissions are missing
        }
    }
}

قراءة أنواع البيانات

لقراءة بيانات تفصيلية معيّنة (مثل معدّل نبضات القلب) حدثت خلال جلسة، استخدِم startTime وendTime للجلسة لفلترة طلب نوع البيانات هذا.

suspend fun readHeartRateData(
    healthConnectClient: HealthConnectClient,
    exerciseSession: ExerciseSessionRecord
) {
    val response = healthConnectClient.readRecords(
        ReadRecordsRequest(
            recordType = HeartRateRecord::class,
            timeRangeFilter = TimeRangeFilter.between(
                exerciseSession.startTime,
                exerciseSession.endTime
            )
        )
    )

    for (heartRateRecord in response.records) {
        for (sample in heartRateRecord.samples) {
            val bpm = sample.beatsPerMinute
        }
    }
}

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

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

  • الكتابة بشكل متكرّر أثناء التتبُّع النشط: بالنسبة إلى التتبُّع النشط، اكتب البيانات فور توفّرها أو بفاصل زمني أقصاه 15 دقيقة.
  • استخدام WorkManager للمزامنة في الخلفية: استخدِم WorkManager لعمليات الكتابة المؤجّلة. استهدِف فاصلًا زمنيًا مدته 15 دقيقة لتحقيق التوازن بين البيانات في الوقت الفعلي وكفاءة البطارية.
  • طلبات الكتابة على دُفعات: لا تكتب كل حدث من أحداث المستشعر بشكل فردي، بل قسِّم طلباتك إلى أجزاء. يمكن لتطبيق Health Connect معالجة ما يصل إلى 1,000 سجلّ لكل طلب كتابة.
  • الحفاظ على ثبات معرّفات الجلسات وفرادتها: استخدِم معرّفات متّسقة لجلساتك، فإذا تم تعديل جلسة أو تحديثها، سيؤدي استخدام المعرّف نفسه إلى منع التعامل معها كجلسة جديدة منفصلة.
  • استخدام التجميع لكل من أنواع البيانات ونقاط المسار: لتقليل الحمل الزائد للإدخال/الإخراج والحفاظ على عمر البطارية، يمكنك تجميع نقاط البيانات في طلب insertRecords واحد بدلاً من كتابة كل نقطة على حدة.
  • تجنُّب كتابة بيانات مكرّرة: استخدام معرّفات العملاء: عند إنشاء سجلّات، اضبط 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"
        )
    )
  • التحقّق من البيانات الحالية: قبل المزامنة، استعلم عن النطاق الزمني لمعرفة ما إذا كانت السجلات من تطبيقك متوفّرة من قبل.
  • التحقّق من صحة بيانات نظام تحديد المواقع العالمي (GPS): استبعِد عيّنات نظام تحديد المواقع العالمي (GPS) المنخفضة الدقة (على سبيل المثال، النقاط التي تتضمّن نصف قطر دقة أفقية عالية) قبل الكتابة إلى ExerciseRoute للتأكّد من أنّ الخريطة تبدو واضحة واحترافية.
  • التأكّد من عدم تداخل الطوابع الزمنية: تأكَّد من أنّ جلسة جديدة لا تبدأ قبل انتهاء الجلسة السابقة، لأنّ الجلسات المتداخلة يمكن أن تتسبّب في حدوث تعارضات في لوحات بيانات اللياقة البدنية واحتسابات الملخّص.
  • تقديم أسباب واضحة للحصول على الإذن: استخدِم مسار Permission.createIntent لتوضيح سبب حاجة تطبيقك إلى الوصول إلى البيانات الصحية، على سبيل المثال: "لمراقبة مؤشرات ضغط الدم وتقديم إحصاءات".
  • إتاحة الإيقاف المؤقت والاستئناف: تأكَّد من أنّ تطبيقك يتعامل مع عمليات الإيقاف المؤقت بشكل سليم. عندما يوقف المستخدم رحلته مؤقتًا، توقَّف عن جمع نقاط المسار وأنواع البيانات لكي يظل متوسط السرعة والمدة دقيقًا.
  • اختبار الجلسات الطويلة: راقِب استهلاك البطارية خلال الجلسات التي تستغرق عدة ساعات للتأكّد من أنّ الفاصل الزمني لتجميع البيانات واستخدام المستشعر لا يستنزفان البطارية.
  • مواءمة الطوابع الزمنية مع معدّلات أجهزة الاستشعار: يمكنك مطابقة الطوابع الزمنية للتسجيل مع معدّل تكرار أجهزة الاستشعار الفعلي للحفاظ على دقة البيانات العالية.

الاختبار

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

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

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

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

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

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

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

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

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

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

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