Google Health API는 exercise 세션 데이터 유형을 사용하여 사용자 운동 세션과 운동 기록을 추적합니다. 세션은 활동 메타데이터, 일시중지 및 재개 이벤트, 랩 또는 분할, 요약 측정항목을 번들로 묶는 컨테이너 역할을 합니다.
애플리케이션에서 운동을 읽고 쓰고 구조화하여 사용자에게 최고의 환경을 제공하는 방법을 알아보세요.
지원되는 데이터 유형
API는 운동 및 활동 세션을 추적하기 위해 다음 데이터 유형을 지원합니다.
| 데이터 유형 | 사용 가능한 작업 |
범위 |
|---|---|---|
|
운동
dataType:
exercisefilter parameter: 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 |
다음 섹션에서는 REST 표현 예시, GPS 경로 처리, 통합 가이드라인을 비롯한 exercise 데이터 유형의 기술 세부정보를 제공합니다.
운동 세션
일일 활동 또는 운동을 exercise 세션 데이터 포인트로 작성합니다. 각 데이터 포인트는 전체 세션을 설명하고, 이벤트 간격(예: 일시중지 및 재개 작업)을 자세히 설명하며, 요약 측정항목(예: 전체 거리, 걸음 수, 평균 심박수)을 제공합니다.
세션 속성
운동 데이터 포인트를 구성할 때는 다음 핵심 구성요소를 확인하세요.
- 세션 시간(
interval): 전체 운동 세션의 시작 시간과 종료 시간, 해당 시점에 활성화된 시간대 오프셋입니다. - 활동 유형(
exerciseType): 수행된 활동의 카테고리입니다(예:RUNNING,WALKING,BIKING,AEROBIC_WORKOUT). 정확한 신체 훈련 유형을 지정합니다. - 표시 이름(
displayName): 운동 세션의 사용자 친화적인 이름입니다. REST API를 통해 생성되면 서버는RUNNING의"Run"과 같이exerciseType의 현지화된 표시 이름을 채웁니다. - 활동 시간(
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 커스텀 메서드를 호출합니다. 이 엔드포인트는 업계 표준 Training Center 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 - 쓰기:
https://www.googleapis.com/auth/googlehealth.activity_and_fitness.writeonly - 읽기:
https://www.googleapis.com/auth/googlehealth.location.readonly
가이드라인
운동 추적을 앱에 통합할 때는 다음 디자인 및 구현 가이드라인을 따르세요.
활성 시간과 총 시간
속도 또는 페이스 측정항목을 계산하려면 항상 startTime과 endTime의 차이가 아닌 activeDuration을 사용하세요. 이렇게 하면 일시중지된 간격이 측정항목을 왜곡하는 것을 방지할 수 있습니다.
예를 들어 사용자가 08:00에 운동을 시작하여 08:35에 완료하면 운동의 총 경과 시간은 2,100초입니다. 사용자가 5분(300초) 동안 운동을 일시중지하고 exerciseEvents에 PAUSE 및 RESUME 이벤트를 포함하는 경우 활동 시간은 "1800s"(2,100 - 300)입니다. API는 활성 기간을 사용하여 평균을 계산하며, 총거리를 2,100초가 아닌 1,800초로 나눕니다.
속도 및 페이스 계산
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에서 세션 집계에 계속 액세스할 수 있습니다.
웹훅을 사용한 실시간 동기화
exercise 데이터 유형을 구독하여 새 운동 데이터를 사용할 수 있게 되면 웹훅을 사용하여 백엔드에 알립니다. 이렇게 하면 운동 후 경험을 실시간으로 트리거할 수 있습니다.
서버가 웹훅 알림을 수신하면 업데이트된 운동의 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"
구독 설정 방법에 대한 자세한 내용은 웹훅 구독을 참조하세요.
일관된 측정항목 유지
완전한 운동 환경을 제공하려면 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를 호출하여 경로 좌표를 다운로드합니다.