الجلسات

في Health Connect، الجلسة هي فاصل زمني ينفّذ فيه المستخدم نشاطًا. نوعا البيانات SleepSessionRecord وExerciseSessionRecord كلاهما جلسات.

تتيح الجلسات للمستخدمين قياس الأداء المستند إلى الوقت على مدار فترة زمنية معيَّنة، مثل معدّل نبضات القلب المستمر أو بيانات الموقع الجغرافي.

تتضمن جلسات ExerciseSessionRecord مجموعة متنوعة من الأنشطة، من الجري إلى كرة الريشة.

تحتوي جلسات SleepSessionRecord على بيانات تسجِّل مراحل النوم، مثل AWAKE وSLEEPING وDEEP.

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

البيانات المرتبطة: يمكن قراءة بيانات Record بشكل منفصل أو إلى جانب الجلسات الأخرى، مثل عدد الخطوات ومعدّل نبضات القلب.

إرشادات عامة

في ما يلي بعض الإرشادات المتعلّقة بأفضل الممارسات حول كيفية التعامل مع الجلسات في Health Connect.

  • يجب استخدام الجلسات لإضافة بيانات من تمرين أو نشاط محدّد، أو من أجل النوم:
suspend fun writeExerciseSession(healthConnectClient: HealthConnectClient) {
    healthConnectClient.insertRecords(
        listOf(
            ExerciseSessionRecord(
                startTime = Instant.parse("2022-05-10T10:00:00.000Z"),
                startZoneOffset = ZoneOffset.of("-08:00"),
                endTime = Instant.parse("2022-05-10T11:00:00.000Z"),
                endZoneOffset = ZoneOffset.of("-08:00"),
                exerciseType = ExerciseSessionRecord.ExerciseType.WALKING,
                title = "My Walk"
            ),
            StepsRecord(
                startTime = Instant.parse("2022-05-10T10:00:00.000Z"),
                startZoneOffset = ZoneOffset.of("-08:00"),
                endTime = Instant.parse("2022-05-10T10:30:00.000Z"),
                endZoneOffset = ZoneOffset.of("-08:00"),
                count = 2800
            ),
StepsRecord(
                startTime = Instant.parse("2022-05-10T10:30:00.000Z"),
                startZoneOffset = ZoneOffset.of("-08:00"),
                endTime = Instant.parse("2022-05-10T11:00:00.000Z"),
                endZoneOffset = ZoneOffset.of("-08:00"),
                count = 3200
            ),  
        )
    )
}
  • عدم استخدام الجلسات للقياسات العامة، مثل أعداد الخطوات اليومية.
  • لا تحتوي بيانات النوع الفرعي على معرف UID، ولكن البيانات المرتبطة بها لها معرفات معرفية فريدة.
  • يجب محاذاة بيانات النوع الفرعي في جلسة مع طوابع زمنية تسلسلية لا تتداخل. ومع ذلك، هناك فجوات مسموح بها.
  • تكون الجلسات مفيدة إذا كان المستخدم يريد ربط البيانات بجلسة (وتتبعها كجزء من) بدلاً من تسجيلها بشكل مستمر.

جلسات النوم

يمكنك قراءة بيانات النوم أو كتابتها في Health Connect. يتم عرض بيانات النوم كجلسة، ويمكن تقسيمها إلى 8 مراحل نوم مختلفة:

  • UNKNOWN: غير محدد أو غير معروف ما إذا كان المستخدم في وضع السكون أم لا.
  • AWAKE: يكون المستخدم مستيقظًا خلال دورة النوم، وليس خلال النهار.
  • SLEEPING: وصف نوم عام أو غير دقيق
  • OUT_OF_BED: ينهض المستخدم من السرير في منتصف جلسة النوم.
  • AWAKE_IN_BED: يستيقظ المستخدم في السرير.
  • LIGHT: يكون المستخدم في دورة نوم خفيفة.
  • DEEP: المستخدِم في دورة نوم عميقة.
  • REM: المستخدم في دورة نوم حركة العين السريعة REM.

تمثل هذه القيم نوع النوم الذي يمر به المستخدم في نطاق زمني. مراحل النوم الكتابية اختيارية، ولكن يُنصح باستخدامها إذا كانت متوفّرة.

كتابة بيانات جلسات النوم مع مراحل النوم أو بدونها

يتكون نوع بيانات SleepSessionRecord على جزأين:

  1. الجلسة الإجمالية، والتي تمتد طوال مدة النوم.
  2. المراحل الفردية أثناء جلسة النوم مثل النوم الخفيف أو النوم العميق.

في ما يلي كيفية إدراج جلسة نوم بدون مراحل:

      SleepSessionRecord(
        title = "weekend sleep",
        startTime = startTime,
        endTime = endTime,
        startZoneOffset = ZoneOffset.UTC,
        endZoneOffset = ZoneOffset.UTC,
      )

إليك كيفية إضافة المراحل التي تغطي الفترة الكاملة لجلسة النوم:

val stages = listOf(
    SleepSessionRecord.Stage(
        startTime = START_TIME
        endTime = END_TIME,
        stage = SleepSessionRecord.STAGE_TYPE_SLEEPING,
    )
)

SleepSessionRecord(
        title = "weekend sleep",
        startTime = START_TIME,
        endTime = END_TIME,
        startZoneOffset = START_ZONE_OFFSET,
        endZoneOffset = END_ZONE_OFFSET,
        stages = stages,
      )
  }

قراءة جلسة النوم

لكل جلسة نوم يتم إرجاعها، يجب عليك التحقق مما إذا كانت بيانات مرحلة النوم متوفرة أيضًا:

suspend fun readSleepSessions(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    val response =
        healthConnectClient.readRecords(
            ReadRecordsRequest(
                SleepSessionRecord::class,
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
            )
        )
    for (sleepRecord in response.records) {
        // Retrieve relevant sleep stages from each sleep record
        val sleepStages = sleepRecord.stages
    }
}

حذف جلسة نوم

هذه هي طريقة حذف جلسة. في هذا المثال، استخدمنا جلسة نوم:

suspend fun deleteSleepSession(
    healthConnectClient: HealthConnectClient,
    sleepRecord: SleepSessionRecord,
) {
    val timeRangeFilter = TimeRangeFilter.between(sleepRecord.startTime, sleepRecord.endTime)
    healthConnectClient.deleteRecords(SleepSessionRecord::class, timeRangeFilter)
}

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

يمكن أن تشمل جلسات التمارين الرياضية أي تمارين، بدءًا من الجري وحتى كرة الريشة.

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

في ما يلي طريقة إنشاء طلب إدراج يتضمن جلسة:

suspend fun writeExerciseSession(healthConnectClient: HealthConnectClient) {
    healthConnectClient.insertRecords(
        listOf(
            ExerciseSessionRecord(
                startTime = START_TIME,
                startZoneOffset = START_ZONE_OFFSET,
                endTime = END_TIME,
                endZoneOffset = END_ZONE_OFFSET,
                exerciseType = ExerciseSessionRecord.ExerciseType.RUNNING,
                title = "My Run"
            ),
            DistanceRecord(
                startTime = START_TIME,
                startZoneOffset = START_ZONE_OFFSET,
                endTime = END_TIME,
                endZoneOffset = END_ZONE_OFFSET,
                distance = 5000.meters
            ),
            // ... other records
        )
    )
}

لاحظ كيف في المثال السابق، تمت إضافة سجل لـ Distance، والذي يمتد طوال مدة الجلسة بالكامل، ولكن يمكن إضافة البيانات بدرجة دقة مختلفة.

إذا قام التطبيق بقياس المسافة بانتظام أثناء الجري، فإن النهج الآخر سيكون تضمين العديد من سجلات المسافة، كل منها يمثل المسافة المغطاة في جزء من الجري.

قراءة جلسة التمرين

فيما يلي مثال على كيفية قراءة جلسة تمرين:

suspend fun readExerciseSessions(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    val response =
        healthConnectClient.readRecords(
            ReadRecordsRequest(
                ExerciseSessionRecord::class,
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
            )
        )
    for (exerciseRecord in response.records) {
        // Process each exercise record
        // Optionally pull in with other data sources of the same time range.
        val distanceRecord =
            healthConnectClient
                .readRecords(
                    ReadRecordsRequest(
                        DistanceRecord::class,
                        timeRangeFilter =
                            TimeRangeFilter.between(
                                exerciseRecord.startTime,
                                exerciseRecord.endTime
                            )
                    )
                )
                .records
    }
}

كتابة بيانات النوع الفرعي

يمكن أن تتألّف الجلسات أيضًا من بيانات فرعية غير إلزامية، ما يثري الجلسة بمعلومات إضافية.

على سبيل المثال، يمكن أن تتضمن جلسات التمارين الصفوف ExerciseSegment وExerciseLap وExerciseRoute:

val segments = listOf(
  ExerciseSegment(
    startTime = Instant.parse("2022-01-02T10:10:10Z"),
    endTime = Instant.parse("2022-01-02T10:10:13Z"),
    segmentType = ActivitySegmentType.BENCH_PRESS,
    repetitions = 373
  )
)

val laps = listOf(
  ExerciseLap(
    startTime = Instant.parse("2022-01-02T10:10:10Z"),
    endTime = Instant.parse("2022-01-02T10:10:13Z"),
    length = 0.meters
  )
)

ExerciseSessionRecord(
  exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_CALISTHENICS,
    startTime = Instant.parse("2022-01-02T10:10:10Z"),
    endTime = Instant.parse("2022-01-02T10:10:13Z"),
  startZoneOffset = ZoneOffset.UTC,
  endZoneOffset = ZoneOffset.UTC,
  segments = segments,
  laps = laps,
  route = route
)

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

هناك طريقتان لحذف جلسة التمرين:

  1. حسب النطاق الزمني.
  2. باستخدام المعرّف الفريد

في ما يلي كيفية حذف بيانات النوع الفرعي وفقًا للنطاق الزمني:

suspend fun deleteExerciseSession(
    healthConnectClient: HealthConnectClient,
    exerciseRecord: ExerciseSessionRecord,
) {
    val timeRangeFilter = TimeRangeFilter.between(sleepRecord.startTime, sleepRecord.endTime)
    healthConnectClient.deleteRecords(SleepSessionRecord::class, timeRangeFilter)
    // delete the associated distance record
    healthConnectClient.deleteRecords(DistanceRecord::class, timeRangeFilter)
}

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

suspend fun deleteExerciseSession(
    healthConnectClient: HealthConnectClient,
    exerciseRecord: ExerciseSessionRecord,
) {
    healthConnectClient.deleteRecords(
        ExerciseSessionRecord::class,
        recordIdsList = listOf(exerciseRecord.metadata.id),
        clientRecordIdsList = emptyList()
    )
}