Hướng dẫn này tương thích với Health Connect phiên bản 1.1.0-alpha11.
Health Connect cung cấp loại dữ liệu bài tập thể dục theo kế hoạch để cho phép các ứng dụng tập luyện ghi kế hoạch tập luyện và cho phép các ứng dụng tập thể dục đọc kế hoạch tập luyện. Bạn có thể đọc lại các bài tập thể dục (bài tập thể dục) đã ghi để phân tích hiệu suất được cá nhân hoá nhằm giúp người dùng đạt được mục tiêu tập luyện.
Phạm vi cung cấp tính năng
Để xác định xem thiết bị của người dùng có hỗ trợ kế hoạch tập thể dục trên Health Connect hay không, hãy kiểm tra xem FEATURE_PLANNED_EXERCISE
có trên ứng dụng khách hay không:
if (healthConnectClient
.features
.getFeatureStatus(
HealthConnectFeatures.FEATURE_PLANNED_EXERCISE
) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE) {
// Feature is available
} else {
// Feature isn't available
}
Hãy xem phần Kiểm tra phạm vi cung cấp của các tính năng để tìm hiểu thêm.
Các quyền bắt buộc
Quyền truy cập vào kế hoạch đào tạo được bảo vệ bằng các quyền sau:
android.permission.health.READ_PLANNED_EXERCISE
android.permission.health.WRITE_PLANNED_EXERCISE
Khai báo các quyền này trong Play Console cho ứng dụng của bạn, cũng như trong tệp kê khai của ứng dụng:
<application>
<uses-permission
android:name="android.permission.health.READ_PLANNED_EXERCISE" />
<uses-permission
android:name="android.permission.health.WRITE_PLANNED_EXERCISE" />
...
</application>
Bạn có trách nhiệm khai báo tất cả các quyền thích hợp mà bạn dự định sử dụng trong thiết bị và ứng dụng của mình. Bạn cũng nên kiểm tra để đảm bảo rằng người dùng đã cấp từng quyền trước khi sử dụng.
Các quyền liên quan
Kế hoạch tập luyện được liên kết với phiên tập thể dục. Do đó, người dùng phải cấp quyền sử dụng từng loại bản ghi liên quan đến một kế hoạch tập luyện để khai thác tối đa tính năng này của Health Connect.
Ví dụ: nếu một kế hoạch tập luyện đo nhịp tim của người dùng trong một loạt các lần chạy, thì nhà phát triển có thể cần phải khai báo và người dùng cấp các quyền sau để ghi phiên tập thể dục và đọc kết quả để đánh giá sau này:
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
Tuy nhiên, thường thì ứng dụng tạo kế hoạch tập luyện và đánh giá hiệu suất so với kế hoạch không giống với ứng dụng sử dụng kế hoạch tập luyện và ghi dữ liệu tập thể dục thực tế. Tuỳ thuộc vào loại ứng dụng, bạn không cần phải có tất cả quyền đọc và ghi. Ví dụ: bạn có thể chỉ cần các quyền sau cho từng loại ứng dụng:
Ứng dụng kế hoạch luyện tập | Ứng dụng tập thể dục |
---|---|
WRITE_PLANNED_EXERCISE |
READ_PLANNED_EXERCISE |
READ_EXERCISE |
WRITE_EXERCISE |
READ_EXERCISE_ROUTE |
WRITE_EXERCISE_ROUTE |
READ_HEART_RATE |
WRITE_HEART_RATE |
Thông tin có trong bản ghi phiên tập thể dục theo kế hoạch
- Tiêu đề của phiên.
- Danh sách các khối bài tập thể dục đã lên kế hoạch.
- Thời gian bắt đầu và kết thúc phiên.
- Loại bài tập.
- Ghi chú cho hoạt động.
- Siêu dữ liệu.
- Mã phiên tập thể dục đã hoàn tất – Mã này được ghi tự động sau khi một phiên tập thể dục liên quan đến phiên tập thể dục đã lên kế hoạch này kết thúc.
Thông tin có trong bản ghi khối bài tập thể dục theo kế hoạch
Khối bài tập thể dục theo kế hoạch chứa danh sách các bước tập thể dục, để hỗ trợ việc lặp lại nhiều nhóm bước (ví dụ: thực hiện một chuỗi bài tập gập người, burpee và gập bụng 5 lần liên tiếp).
- Nội dung mô tả về khối.
- Danh sách các bước tập thể dục theo kế hoạch.
- Số lần lặp lại.
Thông tin có trong bản ghi bước tập thể dục theo kế hoạch
- Nội dung mô tả bước.
- Danh mục bài tập thể dục.
- Loại bài tập.
- Danh sách mục tiêu hiệu suất.
- Mục tiêu hoàn thành.
Phương pháp tổng hợp được hỗ trợ
Không có phương pháp tổng hợp nào được hỗ trợ cho loại dữ liệu này.
Ví dụ về cách sử dụng
Giả sử một người dùng lên kế hoạch chạy bộ trong 90 phút sau hai ngày nữa. Chạy bộ này sẽ có 3 vòng quanh hồ với nhịp tim mục tiêu từ 90 đến 110 nhịp/phút.
- Một phiên tập thể dục theo kế hoạch có những thông tin sau đây do người dùng xác định trong ứng dụng kế hoạch tập luyện:
- Thời gian bắt đầu và kết thúc dự kiến của lần chạy
- Loại bài tập thể dục (chạy bộ)
- Số vòng (số lần lặp lại)
- Mục tiêu hiệu suất cho nhịp tim (từ 90 đến 110 nhịp/phút)
- Thông tin này được nhóm thành các khối và bước tập thể dục, đồng thời được ứng dụng kế hoạch tập thể dục ghi vào Health Connect dưới dạng
PlannedExerciseSessionRecord
. - Người dùng thực hiện phiên đã lên kế hoạch (đang chạy).
- Dữ liệu tập thể dục liên quan đến phiên này được ghi lại theo một trong hai cách:
- Bằng thiết bị đeo trong phiên. Ví dụ: nhịp tim.
Dữ liệu này được ghi vào Health Connect dưới dạng loại bản ghi cho hoạt động. Trong trường hợp này là
HeartRateRecord
. - Do người dùng thực hiện theo cách thủ công sau phiên. Ví dụ: cho biết thời điểm bắt đầu và kết thúc của lần chạy thực tế. Dữ liệu này được ghi vào Health Connect dưới dạng
ExerciseSessionRecord
.
- Bằng thiết bị đeo trong phiên. Ví dụ: nhịp tim.
Dữ liệu này được ghi vào Health Connect dưới dạng loại bản ghi cho hoạt động. Trong trường hợp này là
- Sau đó, ứng dụng kế hoạch tập thể dục sẽ đọc dữ liệu từ Health Connect để đánh giá hiệu suất thực tế so với các mục tiêu do người dùng đặt ra trong phiên tập thể dục theo kế hoạch.
Lên kế hoạch tập thể dục và đặt mục tiêu
Người dùng có thể lên kế hoạch tập thể dục trong tương lai và đặt mục tiêu. Ghi thông tin này vào Health Connect dưới dạng phiên tập thể dục theo kế hoạch.
Trong ví dụ được mô tả trong phần Ví dụ về cách sử dụng, người dùng lên kế hoạch chạy trong 90 phút sau hai ngày nữa. Chạy bộ này sẽ có 3 vòng quanh hồ với nhịp tim mục tiêu từ 90 đến 110 nhịp/phút.
Bạn có thể tìm thấy một đoạn mã như thế này trong trình xử lý biểu mẫu cho một ứng dụng ghi lại các phiên tập thể dục theo kế hoạch vào Health Connect. Bạn cũng có thể tìm thấy thông tin này trong điểm truyền dẫn cho các dịch vụ tích hợp, chẳng hạn như một dịch vụ cung cấp chương trình đào tạo.
// 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()
Ghi lại dữ liệu về hoạt động và bài tập thể dục
Hai ngày sau, người dùng ghi lại phiên tập thể dục thực tế. Ghi dữ liệu này vào Health Connect dưới dạng phiên tập thể dục.
Trong ví dụ này, thời lượng phiên của người dùng khớp chính xác với thời lượng dự kiến.
Bạn có thể tìm thấy đoạn mã sau trong trình xử lý biểu mẫu cho một ứng dụng ghi lại các phiên tập thể dục vào Health Connect. Bạn cũng có thể tìm thấy mã này trong trình xử lý nhập và xuất dữ liệu cho một thiết bị đeo có thể phát hiện và ghi lại các phiên tập thể dục.
insertedPlannedExerciseSessionId
ở đây được sử dụng lại từ ví dụ trước. Trong một ứng dụng thực tế, mã nhận dạng sẽ được xác định bằng cách người dùng chọn một phiên tập thể dục theo kế hoạch trong danh sách các phiên hiện có.
// 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))
Thiết bị đeo cũng ghi lại nhịp tim của người dùng trong suốt quá trình chạy. Bạn có thể sử dụng đoạn mã sau đây để tạo bản ghi trong phạm vi mục tiêu.
Trong một ứng dụng thực tế, bạn có thể tìm thấy các phần chính của đoạn mã này trong trình xử lý cho một thông báo từ thiết bị đeo. Thông báo này sẽ ghi kết quả đo lường vào Health Connect sau khi thu thập.
// 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))
Đánh giá mục tiêu hiệu suất
Vào ngày sau khi người dùng tập thể dục, bạn có thể truy xuất bài tập thể dục đã ghi lại, kiểm tra mọi mục tiêu tập thể dục đã lên kế hoạch và đánh giá các loại dữ liệu bổ sung để xác định xem liệu các mục tiêu đã đặt có được đáp ứng hay không.
Bạn có thể tìm thấy một đoạn mã như thế này trong một công việc định kỳ để đánh giá các mục tiêu hiệu suất hoặc khi tải danh sách bài tập và hiển thị thông báo về các mục tiêu hiệu suất trong ứng dụng.
// 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
}
}
}
}
}
}
}
}