คำแนะนำนี้ใช้ได้กับ 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 Console สําหรับแอปของคุณ รวมถึงในไฟล์ Manifest ของแอป
<application>
<uses-permission
android:name="android.permission.health.READ_PLANNED_EXERCISE" />
<uses-permission
android:name="android.permission.health.WRITE_PLANNED_EXERCISE" />
...
</application>
คุณมีหน้าที่รับผิดชอบในการประกาศสิทธิ์ที่เหมาะสมทั้งหมดที่ตั้งใจจะใช้ในอุปกรณ์และแอป นอกจากนี้ คุณควรตรวจสอบว่าผู้ใช้ได้ให้สิทธิ์แต่ละรายการแล้วก่อนใช้งาน
ขอสิทธิ์จากผู้ใช้
หลังจากสร้างอินสแตนซ์ไคลเอ็นต์แล้ว แอปของคุณจะต้องขอสิทธิ์จากผู้ใช้ ผู้ใช้ต้องได้รับอนุญาตให้ให้หรือปฏิเสธสิทธิ์ได้ทุกเมื่อ
โดยสร้างชุดสิทธิ์สำหรับประเภทข้อมูลที่จำเป็น ตรวจสอบว่าได้ประกาศสิทธิ์ในชุดในไฟล์ Manifest ของ Android ก่อน
// Create a set of permissions for required data types
val PERMISSIONS =
setOf(
HealthPermission.getReadPermission(HeartRateRecord::class),
HealthPermission.getWritePermission(HeartRateRecord::class),
HealthPermission.getReadPermission(PlannedExerciseSessionRecord::class),
HealthPermission.getWritePermission(PlannedExerciseSessionRecord::class),
HealthPermission.getReadPermission(ExerciseSessionRecord::class),
HealthPermission.getWritePermission(ExerciseSessionRecord::class)
)
ใช้ getGrantedPermissions
เพื่อดูว่าแอปได้รับสิทธิ์ที่จําเป็นแล้วหรือยัง หากไม่มี ให้ใช้ createRequestPermissionResultContract
เพื่อขอสิทธิ์เหล่านั้น ซึ่งจะแสดงหน้าจอสิทธิ์ของ Health Connect
// Create the permissions launcher
val requestPermissionActivityContract = PermissionController.createRequestPermissionResultContract()
val requestPermissions = registerForActivityResult(requestPermissionActivityContract) { granted ->
if (granted.containsAll(PERMISSIONS)) {
// Permissions successfully granted
} else {
// Lack of required permissions
}
}
suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient) {
val granted = healthConnectClient.permissionController.getGrantedPermissions()
if (granted.containsAll(PERMISSIONS)) {
// Permissions already granted; proceed with inserting or reading data
} else {
requestPermissions.launch(PERMISSIONS)
}
}
เนื่องจากผู้ใช้สามารถให้หรือเพิกถอนสิทธิ์ได้ทุกเมื่อ แอปของคุณจึงต้องตรวจสอบสิทธิ์ที่มอบให้เป็นระยะๆ และจัดการสถานการณ์ที่สิทธิ์ถูกเพิกถอน
สิทธิ์ที่เกี่ยวข้อง
แผนการฝึกอบรมจะลิงก์กับเซสชันการออกกำลังกาย ดังนั้น ผู้ใช้จึงต้องให้สิทธิ์ใช้เรคคอร์ดแต่ละประเภทที่เกี่ยวข้องกับแผนการฝึกอบรมเพื่อใช้ประโยชน์จากฟีเจอร์นี้ของ 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 |
ข้อมูลที่รวมอยู่ในระเบียนเซสชันการออกกำลังกายที่วางแผนไว้
- ชื่อเซสชัน
- รายการกลุ่มการออกกำลังกายตามแผนที่วางไว้
- เวลาเริ่มต้นและสิ้นสุดของเซสชัน
- ประเภทการออกกำลังกาย
- หมายเหตุสำหรับกิจกรรม
- ข้อมูลเมตา
- รหัสเซสชันการออกกำลังกายที่เสร็จสมบูรณ์ — ระบบจะเขียนข้อมูลนี้โดยอัตโนมัติหลังจากเซสชันการออกกำลังกายที่เกี่ยวข้องกับเซสชันการออกกำลังกายที่วางแผนไว้นี้เสร็จสมบูรณ์
ข้อมูลที่รวมอยู่ในระเบียนบล็อกการออกกำลังกายที่วางแผนไว้
บล็อกการออกกำลังกายที่ตั้งเวลาไว้จะมีรายการขั้นตอนการออกกำลังกายเพื่อรองรับการทำซ้ำของกลุ่มขั้นตอนต่างๆ (เช่น ทำท่าดึงข้อศอกขึ้น ท่า Burpee และท่า Crunch ติดต่อกัน 5 ครั้ง)
- คําอธิบายของบล็อก
- รายการขั้นตอนการออกกำลังกายที่วางแผนไว้
- จํานวนการทําซ้ำ
ข้อมูลที่รวมอยู่ในระเบียนขั้นตอนการออกกำลังกายที่วางแผนไว้
- คำอธิบายขั้นตอน
- หมวดหมู่การออกกําลังกาย
- ประเภทแบบฝึกหัด
- รายการเป้าหมายด้านประสิทธิภาพ
- เป้าหมายการเสร็จสมบูรณ์
การรวมที่รองรับ
ประเภทข้อมูลนี้ไม่รองรับการรวม
ตัวอย่างการใช้งาน
สมมติว่าผู้ใช้วางแผนที่จะวิ่งเป็นเวลา 90 นาทีในอีก 2 วันข้างหน้า การวิ่งนี้จะวิ่งรอบทะเลสาบ 3 รอบโดยมีอัตราการเต้นของหัวใจเป้าหมายระหว่าง 90 ถึง 110 ครั้งต่อนาที
- เซสชันการออกกำลังกายที่วางแผนไว้ซึ่งผู้ใช้กำหนดข้อมูลต่อไปนี้ในแอปแผนการฝึกอบรม
- เวลาที่เริ่มต้นและสิ้นสุดการเรียกใช้ตามแผนที่วางไว้
- ประเภทการออกกำลังกาย (การวิ่ง)
- จำนวนรอบ (จำนวนครั้ง)
- เป้าหมายประสิทธิภาพสำหรับอัตราการเต้นของหัวใจ (ระหว่าง 90 ถึง 110 bpm)
- แอปแผนการฝึกอบรมจะจัดกลุ่มข้อมูลนี้ออกเป็นกลุ่มและขั้นตอนการออกกำลังกาย และเขียนลงใน Health Connect เป็น
PlannedExerciseSessionRecord
- ผู้ใช้ทําเซสชันที่วางแผนไว้ (ทํางานอยู่)
- ระบบจะบันทึกข้อมูลการออกกำลังกายที่เกี่ยวข้องกับเซสชันด้วยวิธีใดวิธีหนึ่งต่อไปนี้
- โดยอุปกรณ์ที่สวมใส่ระหว่างเซสชัน เช่น อัตราการเต้นของหัวใจ
ระบบจะเขียนข้อมูลนี้ลงใน Health Connect เป็นประเภทระเบียนสำหรับกิจกรรม ในกรณีนี้คือ
HeartRateRecord
- ผู้ใช้ดำเนินการด้วยตนเองหลังจากเซสชัน เช่น ระบุการเริ่มต้นและสิ้นสุดของการเรียกใช้จริง ระบบจะเขียนข้อมูลนี้ลงใน Health
Connect เป็น
ExerciseSessionRecord
- โดยอุปกรณ์ที่สวมใส่ระหว่างเซสชัน เช่น อัตราการเต้นของหัวใจ
ระบบจะเขียนข้อมูลนี้ลงใน Health Connect เป็นประเภทระเบียนสำหรับกิจกรรม ในกรณีนี้คือ
- หลังจากนั้น แอปแผนการฝึกอบรมจะอ่านข้อมูลจาก Health Connect เพื่อประเมินประสิทธิภาพจริงเทียบกับเป้าหมายที่ผู้ใช้กำหนดไว้ในเซสชันการออกกำลังกายที่ตั้งไว้
วางแผนการออกกำลังกายและตั้งเป้าหมาย
ผู้ใช้อาจวางแผนการออกกำลังกายในอนาคตและตั้งเป้าหมาย เขียนข้อมูลนี้ลงใน Health Connect เป็นเซสชันการออกกำลังกายที่วางแผนไว้
ในตัวอย่างที่อธิบายไว้ในตัวอย่างการใช้งาน ผู้ใช้วางแผนที่จะวิ่งเป็นเวลา 90 นาทีในอีก 2 วันข้างหน้า การวิ่งนี้จะวิ่งรอบทะเลสาบ 3 รอบโดยมีอัตราการเต้นของหัวใจเป้าหมายระหว่าง 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 = ExerciseSegment.EXERCISE_SEGMENT_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,
metadata = Metadata.manualEntry(
device = Device(type = Device.Companion.TYPE_PHONE)
)
)
val insertedPlannedExerciseSessions =
healthConnectClient.insertRecords(listOf(plannedExerciseSessionRecord)).recordIdsList
val insertedPlannedExerciseSessionId = insertedPlannedExerciseSessions.first()
บันทึกข้อมูลการออกกําลังกายและกิจกรรม
2 วันต่อมา ผู้ใช้บันทึกเซสชันการออกกําลังกายจริง เขียนข้อมูลนี้ลงใน 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,
metadata = Metadata.manualEntry(
device = Device(type = Device.Companion.TYPE_PHONE)
)
)
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,
metadata = Metadata.autoRecorded(
device = Device(type = Device.Companion.TYPE_WATCH)
)
)
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
}
}
}
}
}
}
}
}