برنامه های آموزشی

این راهنما با Health Connect نسخه 1.1.0-alpha11 سازگار است.

Health Connect یک نوع داده تمرین برنامه ریزی شده را ارائه می دهد تا برنامه های آموزشی را قادر سازد برنامه های تمرینی بنویسند و برنامه های تمرینی را برای خواندن برنامه های تمرینی فعال کنند. تمرینات ضبط شده (تمرینات) را می توان برای تجزیه و تحلیل عملکرد شخصی بازخوانی کرد تا به کاربران در دستیابی به اهداف آموزشی خود کمک کند.

در دسترس بودن ویژگی

برای تعیین اینکه آیا دستگاه کاربر از طرح‌های آموزشی در Health Connect پشتیبانی می‌کند یا خیر، در دسترس بودن FEATURE_PLANNED_EXERCISE را در مشتری بررسی کنید:

if (healthConnectClient
     .features
     .getFeatureStatus(
       HealthConnectFeatures.FEATURE_PLANNED_EXERCISE
     ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE) {

  // Feature is available
} else {
  // Feature isn't available
}

برای اطلاعات بیشتر به بررسی در دسترس بودن ویژگی مراجعه کنید.

مجوزهای مورد نیاز

دسترسی به برنامه های آموزشی با مجوزهای زیر محافظت می شود:

  • android.permission.health.READ_PLANNED_EXERCISE
  • android.permission.health.WRITE_PLANNED_EXERCISE

این مجوزها را در کنسول Play برای برنامه خود و همچنین در مانیفست برنامه خود اعلام کنید:

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

شما مسئول اعلام همه مجوزهای مناسبی هستید که قصد دارید در دستگاه ها و برنامه های خود استفاده کنید. همچنین باید بررسی کنید که هر مجوز قبل از استفاده توسط کاربر اعطا شده باشد.

برنامه های تمرینی با جلسات تمرینی مرتبط هستند. بنابراین، کاربر باید برای استفاده کامل از این ویژگی Health Connect اجازه استفاده از هر نوع رکورد مربوط به یک برنامه آموزشی را بدهد.

به عنوان مثال، اگر یک برنامه تمرینی ضربان قلب کاربر را در طول یک سری دویدن اندازه گیری کند، ممکن است نیاز باشد مجوزهای زیر توسط توسعه دهنده اعلام شود و توسط کاربر به منظور نوشتن جلسه تمرین و خواندن نتایج برای ارزیابی بعدی لازم باشد:

  • android.permission.health.READ_EXERCISE
  • android.permission.health.READ_EXERCISE_ROUTE
  • android.permission.health.READ_HEART_RATE
  • android.permission.health.WRITE_EXERCISE
  • android.permission.health.WRITE_EXERCISE_ROUTE
  • android.permission.health.WRITE_HEART_RATE

با این حال، اغلب برنامه‌ای که برنامه‌های تمرینی ایجاد می‌کند و عملکرد را در برابر برنامه‌ها ارزیابی می‌کند، با برنامه‌ای که برنامه‌های تمرینی را مصرف می‌کند و داده‌های واقعی تمرین را می‌نویسد، یکسان نیست. بسته به نوع برنامه، همه مجوزهای خواندن و نوشتن مورد نیاز نیستند. برای مثال، ممکن است برای هر نوع برنامه فقط به این مجوزها نیاز داشته باشید:

اپلیکیشن طرح آموزشی برنامه تمرین
WRITE_PLANNED_EXERCISE READ_PLANNED_EXERCISE
READ_EXERCISE WRITE_EXERCISE
READ_EXERCISE_ROUTE WRITE_EXERCISE_ROUTE
READ_HEART_RATE WRITE_HEART_RATE

اطلاعات موجود در یک رکورد جلسه تمرین برنامه ریزی شده

  • عنوان جلسه
  • لیستی از بلوک های ورزشی برنامه ریزی شده
  • زمان شروع و پایان جلسه
  • نوع تمرین
  • نکات مربوط به فعالیت
  • فراداده.
  • شناسه جلسه تمرین تکمیل شده - این به طور خودکار پس از تکمیل یک جلسه تمرین مربوط به این جلسه تمرین برنامه ریزی شده نوشته می شود.

اطلاعات موجود در یک رکورد بلوک تمرین برنامه ریزی شده

یک بلوک تمرینی برنامه‌ریزی‌شده حاوی فهرستی از مراحل تمرین است که از تکرار گروه‌های مختلف گام‌ها پشتیبانی می‌کند (به‌عنوان مثال، یک دنباله از فر کردن بازوها، آروغ زدن، و کرانچ‌ها را پنج بار پشت سر هم انجام دهید).

اطلاعاتی که در یک رکورد گام تمرین برنامه ریزی شده گنجانده شده است

تجمعات پشتیبانی شده

هیچ تجمع پشتیبانی شده ای برای این نوع داده وجود ندارد.

مثال استفاده

فرض کنید یک کاربر دو روز بعد برنامه 90 دقیقه ای را دارد. این دوی شامل سه دور دور یک دریاچه با ضربان قلب هدف بین 90 تا 110 ضربه در دقیقه است.

  1. یک جلسه تمرین برنامه ریزی شده با موارد زیر توسط کاربر در برنامه برنامه تمرینی تعریف می شود:
    1. شروع و پایان برنامه ریزی شده اجرا
    2. نوع ورزش (دویدن)
    3. تعداد دور (تکرار)
    4. هدف عملکرد برای ضربان قلب (بین 90 تا 110 ضربه در دقیقه)
  2. این اطلاعات در بلوک‌ها و مراحل تمرین گروه‌بندی می‌شود و توسط برنامه برنامه تمرینی به عنوان یک PlannedExerciseSessionRecord در Health Connect نوشته می‌شود.
  3. کاربر جلسه برنامه ریزی شده (در حال اجرا) را انجام می دهد.
  4. داده های تمرین مربوط به جلسه یا ثبت می شود:
    1. توسط یک پوشیدنی در طول جلسه. مثلا ضربان قلب. این داده به عنوان نوع رکورد برای فعالیت در Health Connect نوشته می شود. در این مورد، HeartRateRecord .
    2. به صورت دستی توسط کاربر پس از جلسه. به عنوان مثال، شروع و پایان اجرای واقعی را نشان می دهد. این داده به عنوان ExerciseSessionRecord در Health Connect نوشته می شود.
  5. در زمان بعدی، برنامه برنامه تمرینی داده ها را از Health Connect می خواند تا عملکرد واقعی را در برابر اهداف تعیین شده توسط کاربر در جلسه تمرین برنامه ریزی شده ارزیابی کند.

تمرین ها را برنامه ریزی کنید و اهداف تعیین کنید

یک کاربر ممکن است تمرینات خود را در آینده برنامه ریزی کند و اهدافی را تعیین کند. این را به عنوان یک جلسه تمرین برنامه ریزی شده در Health Connect بنویسید.

در مثالی که در مثال استفاده توضیح داده شده است، کاربر یک اجرای 90 دقیقه ای از دو روز بعد را برنامه ریزی می کند. این دوی شامل سه دور دور یک دریاچه با ضربان قلب هدف بین 90 تا 110 ضربه در دقیقه است.

قطعه‌ای مانند این را می‌توان در کنترل‌کننده فرم برنامه‌ای یافت که جلسات تمرین برنامه‌ریزی‌شده را در Health Connect ثبت می‌کند. همچنین می‌توان آن را در نقطه ورود برای ادغام‌ها یافت، مثلاً با سرویسی که آموزش ارائه می‌دهد.

// Ensure the user has granted all necessary permissions for this task
val grantedPermissions =
    healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
      HealthPermission.getWritePermission(PlannedExerciseSessionRecord::class))) {
    // The user hasn't granted the app permission to write planned exercise session data.
    return
}

val plannedDuration = Duration.ofMinutes(90)
val plannedStartDate = LocalDate.now().plusDays(2)

val plannedExerciseSessionRecord = PlannedExerciseSessionRecord(
    startDate = plannedStartDate,
    duration = plannedDuration,
    exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
    blocks = listOf(
        PlannedExerciseBlock(
            repetitions = 1, steps = listOf(
                PlannedExerciseStep(
                    exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
                    exercisePhase = PlannedExerciseStep.EXERCISE_PHASE_ACTIVE,
                    completionGoal = ExerciseCompletionGoal.RepetitionsGoal(repetitions = 3),
                    performanceTargets = listOf(
                        ExercisePerformanceTarget.HeartRateTarget(
                            minHeartRate = 90.0, maxHeartRate = 110.0
                        )
                    )
                ),
            ), description = "Three laps around the lake"
        )
    ),
    title = "Run at lake",
    notes = null
)
val insertedPlannedExerciseSessions =
    healthConnectClient.insertRecords(listOf(plannedExerciseSessionRecord)).recordIdsList
val insertedPlannedExerciseSessionId = insertedPlannedExerciseSessions.first()

داده های تمرین و فعالیت را ثبت کنید

دو روز بعد، کاربر جلسه تمرین واقعی را ثبت می کند. این را به عنوان یک جلسه ورزشی در Health Connect بنویسید.

در این مثال، مدت زمان جلسه کاربر دقیقاً با مدت زمان برنامه ریزی شده مطابقت داشت.

قطعه زیر ممکن است در فرم کنترل کننده برنامه‌ای که جلسات تمرین را در Health Connect ثبت می‌کند پیدا شود. همچنین ممکن است در کنترل‌کننده‌های دریافت و صادرات داده‌ها برای پوشیدنی‌هایی که قادر به شناسایی و ثبت جلسات تمرین هستند، یافت شود.

insertedPlannedExerciseSessionId در اینجا از مثال قبلی مجددا استفاده شده است. در یک برنامه واقعی، شناسه با انتخاب یک جلسه تمرین برنامه ریزی شده از لیست جلسات موجود توسط کاربر تعیین می شود.

// Ensure the user has granted all necessary permissions for this task
val grantedPermissions =
    healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
      HealthPermission.getWritePermission(ExerciseSessionRecord::class))) {
    // The user doesn't granted the app permission to write exercise session data.
    return
}

val sessionDuration = Duration.ofMinutes(90)
val sessionEndTime = Instant.now()
val sessionStartTime = sessionEndTime.minus(sessionDuration)

val exerciseSessionRecord = ExerciseSessionRecord(
    startTime = sessionStartTime,
    startZoneOffset = ZoneOffset.UTC,
    endTime = sessionEndTime,
    endZoneOffset = ZoneOffset.UTC,
    exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
    segments = listOf(
        ExerciseSegment(
            startTime = sessionStartTime,
            endTime = sessionEndTime,
            repetitions = 3,
            segmentType = ExerciseSegment.EXERCISE_SEGMENT_TYPE_RUNNING
        )
    ),
    title = "Run at lake",
    plannedExerciseSessionId = insertedPlannedExerciseSessionId,
)
val insertedExerciseSessions =
    healthConnectClient.insertRecords(listOf(exerciseSessionRecord))

یک پوشیدنی همچنین ضربان قلب آنها را در طول دویدن ثبت می کند. قطعه زیر می تواند برای ایجاد رکورد در محدوده هدف استفاده شود.

در یک برنامه واقعی، قطعات اصلی این قطعه ممکن است در کنترلر برای پیامی از یک پوشیدنی پیدا شود، که پس از جمع آوری، اندازه گیری را در Health Connect می نویسد.

// Ensure the user has granted all necessary permissions for this task
val grantedPermissions =
    healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
      HealthPermission.getWritePermission(HeartRateRecord::class))) {
    // The user doesn't granted the app permission to write heart rate record data.
    return
}

val samples = mutableListOf<HeartRateRecord.Sample>()
var currentTime = sessionStartTime
while (currentTime.isBefore(sessionEndTime)) {
    val bpm = Random.nextInt(21) + 90
    val heartRateRecord = HeartRateRecord.Sample(
        time = currentTime,
        beatsPerMinute = bpm.toLong(),
    )
    samples.add(heartRateRecord)
    currentTime = currentTime.plusSeconds(180)
}

val heartRateRecord = HeartRateRecord(
    startTime = sessionStartTime,
    startZoneOffset = ZoneOffset.UTC,
    endTime = sessionEndTime,
    endZoneOffset = ZoneOffset.UTC,
    samples = samples,
)
val insertedHeartRateRecords = healthConnectClient.insertRecords(listOf(heartRateRecord))

اهداف عملکرد را ارزیابی کنید

روز بعد از تمرین کاربر، می‌توانید تمرین ثبت‌شده را بازیابی کنید، اهداف ورزشی برنامه‌ریزی‌شده را بررسی کنید و انواع داده‌های اضافی را برای تعیین اینکه آیا اهداف تعیین‌شده برآورده شده‌اند، ارزیابی کنید.

قطعه ای مانند این احتمالاً در یک کار دوره ای برای ارزیابی اهداف عملکرد یا هنگام بارگیری لیستی از تمرین ها و نمایش اعلان در مورد اهداف عملکرد در یک برنامه یافت می شود.

// Ensure the user has granted all necessary permissions for this task
val grantedPermissions =
     healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.containsAll(
        listOf(
            HealthPermission.getReadPermission(ExerciseSessionRecord::class),
            HealthPermission.getReadPermission(PlannedExerciseSessionRecord::class),
            HealthPermission.getReadPermission(HeartRateRecord::class)
        )
    )
) {
    // The user doesn't granted the app permission to read exercise session record data.
    return
}

val searchDuration = Duration.ofDays(1)
val searchEndTime = Instant.now()
val searchStartTime = searchEndTime.minus(searchDuration)

val response = healthConnectClient.readRecords(
    ReadRecordsRequest<ExerciseSessionRecord>(
        timeRangeFilter = TimeRangeFilter.between(searchStartTime, searchEndTime)
    )
)
for (exerciseRecord in response.records) {
    val plannedExerciseRecordId = exerciseRecord.plannedExerciseSessionId
    val plannedExerciseRecord =
        if (plannedExerciseRecordId == null) null else healthConnectClient.readRecord(
            PlannedExerciseSessionRecord::class, plannedExerciseRecordId
        ).record
    if (plannedExerciseRecord != null) {
        val aggregateRequest = AggregateRequest(
            metrics = setOf(HeartRateRecord.BPM_AVG),
            timeRangeFilter = TimeRangeFilter.between(
                exerciseRecord.startTime, exerciseRecord.endTime
            ),
        )
        val aggregationResult = healthConnectClient.aggregate(aggregateRequest)

        val maxBpm = aggregationResult[HeartRateRecord.BPM_MAX]
        val minBpm = aggregationResult[HeartRateRecord.BPM_MIN]
        if (maxBpm != null && minBpm != null) {
            plannedExerciseRecord.blocks.forEach { block ->
                block.steps.forEach { step ->
                    step.performanceTargets.forEach { target ->
                        when (target) {
                            is ExercisePerformanceTarget.HeartRateTarget -> {
                                val minTarget = target.minHeartRate
                                val maxTarget = target.maxHeartRate
                                if(
                                    minBpm >= minTarget && maxBpm <= maxTarget
                                ) {
                                  // Success!
                                }
                            }
                            // Handle more target types
                            }
                        }
                    }
                }
            }
        }
    }
}