המדריך הזה תואם לגרסה 1.1.0-alpha11 של Health Connect.
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 Console, וגם במניפסט של האפליקציה:
<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 פעימות לדקה.
- סשן אימון מתוכנן עם הפרטים הבאים מוגדר על ידי המשתמש באפליקציית תוכנית אימונים:
- שעת ההתחלה והסיום המתוכננות של הריצה
- סוג הפעילות הגופנית (ריצה)
- מספר הקפות (חזרות)
- יעד הביצועים של הדופק (בין 90 ל-110 פעימות בדקה)
- המידע הזה מקובץ בבלוק של תרגילים ובשלבים, והאפליקציה של תוכנית האימון כותבת אותו ב-Health Connect בתור
PlannedExerciseSessionRecord
. - המשתמש מבצע את הסשן המתוכנן (בפעילות).
- נתוני הפעילות הגופנית שקשורים לסשן מתועדים באחת מהדרכים הבאות:
- על ידי מכשיר לביש במהלך הסשן. לדוגמה, דופק.
הנתונים האלה נכתבים ב-Health Connect כסוג הרשומה של הפעילות. במקרה הזה,
HeartRateRecord
. - באופן ידני על ידי המשתמש אחרי הסשן. לדוגמה, לציין את תחילת הריצה ואת סופה בפועל. הנתונים האלה נכתבים ב-Health
Connect כ-
ExerciseSessionRecord
.
- על ידי מכשיר לביש במהלך הסשן. לדוגמה, דופק.
הנתונים האלה נכתבים ב-Health Connect כסוג הרשומה של הפעילות. במקרה הזה,
- בשלב מאוחר יותר, אפליקציית תוכנית האימון קוראת נתונים מ-Health Connect כדי להעריך את הביצועים בפועל בהשוואה ליעדים שהמשתמש קבע בסשן האימון המתוכנן.
תכנון תרגילים והגדרת יעדים
המשתמש יכול לתכנן את האימון שלו בעתיד ולהגדיר יעדים. כותבים את זה ב-Health Connect כסשן אימון מתוכנן.
בדוגמה שמתוארת בקטע דוגמה לשימוש, המשתמש מתכנן ריצה של 90 דקות בעוד יומיים. הריצה הזו תכלול שלוש הקפות סביב אגם, עם יעד דופק של 90 עד 110 פעימות בדקה.
קטע קוד כזה עשוי להופיע במטפל בטופס של אפליקציה שמתעדת סשנים מתוכננים של אימון ב-Health Connect. הוא יכול להופיע גם בנקודת הטמעת הנתונים (ingest) של השילובים, למשל עם שירות שמציע הדרכה.
// 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
}
}
}
}
}
}
}
}