Google Health API 使用 exercise 会话数据类型跟踪用户的锻炼课程和锻炼记录。一个时段相当于一个容器,其中包含活动元数据、暂停和恢复事件、圈数或分段以及摘要指标。
了解如何在应用中读取、写入和构建锻炼数据,以便为用户提供最佳体验。
支持的数据类型
该 API 支持以下数据类型,用于跟踪锻炼和活动时段:
| 数据类型 | 可用的 操作 |
范围 |
|---|---|---|
|
锻炼
dataType:
exercise过滤条件参数: exercise
记录类型:练习
兼容的设备
|
list、get、reconcile、create、update、batchDelete | .activity_and_fitness.readonly.activity_and_fitness.writeonly |
相关遥测数据类型
虽然锻炼时段使用 exercise 数据类型作为容器,但穿戴式设备也会在锻炼时段内记录详细的高频遥测数据。在 Google Health API 中,这些精细的日内遥测数据类型是只读的,无法直接通过其自己的 REST 端点创建或修改。通过 REST API 写入锻炼时段时,请在 exercise 数据点的 metricsSummary 对象中传递汇总锻炼指标。
下表将 exercise.metricsSummary 中的摘要字段映射到相应的只读日内遥测数据类型,您可以查询该锻炼时间窗口内的这些数据类型:
摘要字段 (metricsSummary) |
日内遥测数据类型名称 | API 遥测数据类型 ID(只读) | 过滤条件字段 (?filter=) |
必需的读取 OAuth 范围 |
|---|---|---|---|---|
caloriesKcal |
活动消耗热量 | active-energy-burned |
active_energy_burned.interval.start_time |
activity_and_fitness.readonly |
distanceMillimeters |
距离 | distance |
distance.interval.start_time |
activity_and_fitness.readonly |
steps |
步骤 | steps |
steps.interval.start_time |
activity_and_fitness.readonly |
averageHeartRateBeatsPerMinute |
心率 | heart-rate |
heart_rate.sample_time.physical_time |
health_metrics_and_measurements.readonly |
activeZoneMinutes |
活跃区间分钟数 | active-zone-minutes |
active_zone_minutes.interval.start_time |
activity_and_fitness.readonly |
以下部分提供了 exercise 数据类型的技术详细信息,包括 REST 表示法示例、GPS 路线处理和集成指南。
锻炼时段
将日常活动或锻炼记录为 exercise 会话数据点。每个数据点都描述了整体锻炼、详细事件间隔(例如暂停和恢复操作),并提供了摘要指标(例如总距离、步数和平均心率)。
会话属性
在构建锻炼数据点时,请验证以下核心组件:
- 练习时间 (
interval):整个锻炼练习的开始时间和结束时间,以及这些时间点有效的时区偏移量。 - 活动类型 (
exerciseType):所执行活动的类别(例如RUNNING、WALKING、BIKING或AEROBIC_WORKOUT)。指定确切的体能训练类型。 - 显示名称 (
displayName):锻炼课程的人性化名称。通过 REST API 创建时,服务器会填充exerciseType的本地化显示名称,例如RUNNING的"Run"。 - 活动时长 (
activeDuration):锻炼的实际活动时间,不包括暂停的时间间隔。标准格式使用Duration格式(例如"1800s")。在服务器上,activeDuration的计算方法是从会话interval中减去exerciseEvents中的任何PAUSE/RESUME或AUTO_PAUSE/AUTO_RESUME间隔。
摘要指标
metricsSummary 嵌套对象包含在整个锻炼时段内计算的总指标和平均指标:
caloriesKcal:锻炼期间消耗的总活动卡路里数,以千卡 (kcal) 为单位。distanceMillimeters:总距离,以毫米为单位,以便在不同单位之间保持高精度。steps:锻炼期间的总步数。averageHeartRateBeatsPerMinute:用户在活跃分钟数内的平均心率。activeZoneMinutes:锻炼期间获得的累计活跃区间分钟数。averageSpeedMillimetersPerSecond:平均移动速度(毫米/秒)。averagePaceSecondsPerMeter:练习活跃分钟数内的平均配速,以秒/米为单位。elevationGainMillimeters:活动期间的总爬升高度。
圈数和分段
对于从受支持设备同步的涉及圈数的锻炼(例如跑道跑步或泳池游泳),splitSummaries会按圈数或分段对锻炼进行分段。
每个拆分包含:
- 特定的
startTime和endTime。 - 表示真实单圈用时的
activeDuration。 - 仅限定于该细分的
metricsSummary。 - 用于定义分块边界的
splitType(例如DISTANCE、DURATION或MANUAL)。
锻炼活动
如需准确计算活跃时长,请使用 exerciseEvents 跟踪状态转换(例如手动或自动暂停事件)。
每个事件都包含时间戳 (eventTime) 和类型:
START/STOP:表示用户明确开始或停止记录的时间戳边界。PAUSE/RESUME:指示会话何时手动暂停或恢复。AUTO_PAUSE/AUTO_RESUME:表示由传感器驱动的自动暂停/恢复。
写入锻炼时段
如需创建、更新或导入锻炼课程,请将数据点写入 exercise 数据类型集合。使用 create dataPoints 端点。
REST 表示法示例
以下示例展示了如何使用 POST 方法写入锻炼时段:
请求
POST https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints
Authorization: Bearer access-token
Content-Type: application/json
{
"dataSource": {
"recordingMethod": "ACTIVELY_MEASURED",
"platform": "GOOGLE_WEB_API"
},
"exercise": {
"interval": {
"startTime": "2026-04-20T08:00:00Z",
"startUtcOffset": "0s",
"endTime": "2026-04-20T08:35:00Z",
"endUtcOffset": "0s"
},
"exerciseType": "RUNNING",
"activeDuration": "1800s",
"metricsSummary": {
"caloriesKcal": 380.0,
"distanceMillimeters": 5000000.0,
"steps": "6200",
"averageHeartRateBeatsPerMinute": "148",
"averagePaceSecondsPerMeter": 0.36
},
"exerciseEvents": [
{
"eventTime": "2026-04-20T08:15:00Z",
"eventUtcOffset": "0s",
"exerciseEventType": "PAUSE"
},
{
"eventTime": "2026-04-20T08:20:00Z",
"eventUtcOffset": "0s",
"exerciseEventType": "RESUME"
}
]
}
}响应
{
"done": true,
"response": {
"@type": "type.googleapis.com/google.devicesandservices.health.v4.DataPoint",
"name": "users/999298779973222220/dataTypes/exercise/dataPoints/3054085373369111216",
"dataSource": {
"recordingMethod": "ACTIVELY_MEASURED",
"application": {
"googleWebClientId": "438076457939-example.apps.googleusercontent.com"
},
"platform": "GOOGLE_WEB_API"
},
"exercise": {
"interval": {
"startTime": "2026-04-20T08:00:00Z",
"startUtcOffset": "0s",
"endTime": "2026-04-20T08:35:00Z",
"endUtcOffset": "0s"
},
"exerciseType": "RUNNING",
"metricsSummary": {
"caloriesKcal": 380,
"distanceMillimeters": 5000000,
"steps": "6200",
"averagePaceSecondsPerMeter": 0.36,
"averageHeartRateBeatsPerMinute": "148"
},
"exerciseMetadata": {},
"displayName": "Run",
"activeDuration": "1800s",
"exerciseEvents": [
{
"eventTime": "2026-04-20T08:15:00Z",
"eventUtcOffset": "0s",
"exerciseEventType": "PAUSE"
},
{
"eventTime": "2026-04-20T08:20:00Z",
"eventUtcOffset": "0s",
"exerciseEventType": "RESUME"
}
],
"updateTime": "2026-04-20T08:35:10.123456Z",
"createTime": "2026-04-20T08:35:10.123456Z"
}
}
}GPS 路线和位置信息跟踪
该 API 会直接在 exercise 数据点内保存基本锻炼总结,但会将详细的位置记录和 GPS 路线坐标作为单独的数据流进行处理。
如需下载户外锻炼的详细路线数据,请调用 exportExerciseTcx 自定义方法。此端点会以业界标准的训练中心 XML (TCX) 格式返回路线。
导出 GPS 路线
请求
GET https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints/exercise-data-point-id:exportExerciseTcx?alt=media Authorization: Bearer access-token
响应
包含 Content-Type: application/tcx+xml 和标头的 HTTP 载荷,用于指示浏览器保存文件。
<?xml version="1.0" encoding="UTF-8"?>
<TrainingCenterDatabase xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2">
<Activities>
<Activity Sport="Running">
<Id>2026-04-20T08:00:00Z</Id>
<Lap StartTime="2026-04-20T08:00:00Z">
<TotalTimeSeconds>1800</TotalTimeSeconds>
<DistanceMeters>5000</DistanceMeters>
<Calories>380</Calories>
<Intensity>Active</Intensity>
<TriggerMethod>Manual</TriggerMethod>
<Track>
<Trackpoint>
<Time>2026-04-20T08:00:00Z</Time>
<Position>
<LatitudeDegrees>37.7749</LatitudeDegrees>
<LongitudeDegrees>-122.4194</LongitudeDegrees>
</Position>
<AltitudeMeters>15.0</AltitudeMeters>
<DistanceMeters>0.0</DistanceMeters>
</Trackpoint>
</Track>
</Lap>
</Activity>
</Activities>
</TrainingCenterDatabase>必需的范围和位置
如需使用 GPS 路线和位置信息跟踪功能,您的应用必须请求以下 OAuth 范围:
- 读取:
https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly - Write:
https://www.googleapis.com/auth/googlehealth.activity_and_fitness.writeonly - 读取:
https://www.googleapis.com/auth/googlehealth.location.readonly
指南
将锻炼跟踪功能集成到应用中时,请遵循以下设计和实现指南。
活跃时长与总时长
如需计算速度或配速指标,请始终使用 activeDuration,而不是 startTime 与 endTime 之间的差值。这样可以防止暂停的时间间隔
影响指标。
例如,如果用户在 08:00 开始锻炼,并在 08:35 结束锻炼,则锻炼的总时长为 2,100 秒。如果用户暂停锻炼 5 分钟(300 秒),并且您在 exerciseEvents 中添加了 PAUSE 和 RESUME 事件,则活跃时长为 "1800s"(2,100 - 300)。该 API 使用活跃时长来计算平均值,即用总距离除以 1,800 秒(而非 2,100 秒)。
速度和配速计算
Google Health API 会使用标准公式来计算速度和配速:
- 速度 =
distance / time(hour) - 配速 =
time(seconds) / distance
请求中指定的 Accept-Language 标头决定了距离单位。
尽早请求位置信息
如果您的应用会绘制锻炼路线,除了活动和健身范围之外,还应请求位置信息权限和 Google Health location 范围。在查看 GPS 锻炼时,向用户说明您的应用为何需要位置信息范围。
当您的应用请求位置信息范围 (https://www.googleapis.com/auth/googlehealth.location.readonly) 时,Google OAuth 会向用户显示权限请求提示。向用户说明,此权限对于呈现路线叠加层和导出 GPS 轨迹文件 (TCX) 是必需的。如果用户授予活动范围但拒绝位置信息权限,exportExerciseTcx 会返回授权错误,但您仍然可以在 metricsSummary 中访问会话汇总数据。
使用 webhook 进行同步
订阅 exercise 数据类型,以便在有新的锻炼数据可用时使用 webhook 通知后端。这样,您就可以自动触发锻炼后体验。
当您的服务器收到网络钩子通知时,通知中会包含更新后的锻炼的 healthUserId 和民用时间间隔 (civilIso8601TimeInterval)。您的服务器应立即使用 204 No Content 确认通知,异步处理载荷,并使用 exercise.interval.civil_start_time 过滤条件查询对账后的 exercise 端点(请注意,exercise 仅支持按 civil_start_time 过滤):
GET https://health.googleapis.com/v4/users/healthUserId/dataTypes/exercise/dataPoints:reconcile?filter=exercise.interval.civil_start_time >= "2026-04-20T08:00:00" AND exercise.interval.civil_start_time < "2026-04-20T10:00:00"
如需详细了解如何设置订阅,请参阅 Webhook 订阅。
保持指标一致
为了提供完整的锻炼体验,请在写入 exercise 练习时添加摘要指标,并在呈现详细图表时使用时间范围过滤条件查询只读遥测端点。
写入锻炼总结指标(写入路径)
将已完成的锻炼导入或写入 Google Health API 时,请在 exercise 数据点的 metricsSummary 对象中添加锻炼的汇总遥测指标(steps、caloriesKcal、distanceMillimeters、averageHeartRateBeatsPerMinute 和 averagePaceSecondsPerMeter):
POST https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints
查询图表的详细数据(读取路径)
如需为特定练习构建锻炼信息中心或图表,请查询该锻炼时间范围内的协调遥测端点:
使用
civil_start_time过滤条件从exercise端点提取锻炼课程,以获取其interval和metricsSummary:GET https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints:reconcile?filter=exercise.interval.civil_start_time >= "2026-04-20T00:00:00" AND exercise.interval.civil_start_time < "2026-04-21T00:00:00"
使用会话的
interval.startTime和interval.endTime查询该物理时间窗口的遥测端点。如果
exerciseMetadata.hasGps为true,则调用exportExerciseTcx以下载路线坐标。