使用 Google Health API 開發運動體驗

Google Health API 會使用exercise工作階段資料類型,追蹤使用者運動時段和運動記錄。工作階段是容器,可將活動中繼資料、暫停和繼續事件、單圈或分段,以及摘要指標捆綁在一起。

瞭解如何在應用程式中讀取、寫入及建構訓練,為使用者提供最佳體驗。

支援的資料類型

這項 API 支援下列資料類型,可追蹤運動和活動記錄:

表格:Google Health API 運動資料類型
資料類型
  dataType
  filter 參數
記錄
類型
可用的
作業
範圍 Webhook
支援
支援真正的零
運動
  exercise
  exercise
工作階段 list、get、reconcile、create、update、batchDelete activity_and_fitness

雖然運動健身活動會使用 exercise 資料型別做為容器,但一般運動健身追蹤器會在活動期間寫入及讀取詳細的高頻率遙測資料。這些測量值 (例如心率或步數) 必須使用各自的資料類型讀取或寫入。

下表列出 exercise 資料型別的 metricsSummary 物件內欄位,與 Google Health API 對應的原始遙測資料型別之間的對應關係:

摘要欄位 (metricsSummary) 當日遙測資料類型名稱 API 遙測資料類型 ID
caloriesKcal 活動時消耗的熱量 active-energy-burned
distanceMillimeters 距離 distance
steps 步驟 steps
averageHeartRateBeatsPerMinute 心跳速率 heart-rate
activeZoneMinutes 活動區間分鐘數 active-zone-minutes

以下各節提供 exercise 資料類型的技術詳細資料,包括 REST 代表性範例、GPS 路線處理方式和整合指南。

健身活動

將每日活動或運動寫入為 exercise 時段資料點。每個資料點都會說明整體工作階段、詳細事件間隔 (例如暫停和繼續動作),並提供摘要指標 (例如總距離、步數和平均心率)。

工作階段屬性

建構運動資料點時,請確認下列核心元件:

  • 運動時間 (interval):整體運動時間的開始和結束時間,以及這些時間點的時區偏移量。
  • 活動類型 (exerciseType):執行的活動類別 (例如 RUNNINGWALKINGBIKINGAEROBIC_WORKOUT)。請指定確切的體能訓練類型。
  • 顯示名稱 (displayName):運動訓練工作階段的簡單名稱 (例如「下午越野跑」)。
  • 活動時間 (activeDuration):運動的實際活動時間,不含暫停間隔。標準格式使用 Duration 格式 (例如 "1800s")。

摘要指標

metricsSummary 巢狀物件包含在整個運動期間計算的總計和平均指標:

  • caloriesKcal:運動期間燃燒的總卡路里燃燒量,以千卡 (kcal) 為單位。
  • distanceMillimeters:總移動距離,以毫米為單位,確保各單位的精確度。
  • steps:運動期間的總步數。
  • averageHeartRateBeatsPerMinute:使用者在課程活動分鐘數期間的平均心率。
  • activeZoneMinutes:運動期間累積的活動區間分鐘數。
  • averageSpeedMillimetersPerSecond:平均移動速度,單位為每秒公釐。
  • averagePaceSecondsPerMeter:在活動期間的活動分鐘數內,平均配速 (以每公尺秒數為單位)。
  • elevationGainMillimeters:工作階段期間的總爬升高度。

計圈和分段

如果運動包含圈數 (例如田徑跑步或泳池游泳),請使用 splitSummaries

每個分割畫面包含:

  • 特定 startTimeendTime
  • activeDuration 代表實際單圈時間。
  • metricsSummary 僅限該區隔。
  • 用來定義分割邊界 的 splitType,例如 DISTANCEDURATIONMANUAL

運動事件

如要準確計算有效時間,請使用 exerciseEvents 追蹤狀態轉換 (例如手動或自動暫停事件)。

每個事件都包含時間戳記 (eventTime) 和類型:

  • START / STOP:表示使用者明確開始或停止錄製的時間戳記。
  • PAUSE / RESUME:指出工作階段手動暫停或繼續的時間。
  • AUTO_PAUSE / AUTO_RESUME:表示感應器驅動的自動暫停/繼續。

寫入訓練活動

如要建立、更新或匯入訓練活動,請將資料點寫入 exercise 資料類型集合。使用 create 資料點端點。

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"
  },
  "exercise": {
    "interval": {
      "startTime": "2026-04-20T08:00:00Z",
      "startUtcOffset": "0s",
      "endTime": "2026-04-20T08:35:00Z",
      "endUtcOffset": "0s"
    },
    "exerciseType": "RUNNING",
    "displayName": "Morning Trail Run",
    "activeDuration": "1800s",
    "metricsSummary": {
      "caloriesKcal": 380.0,
      "distanceMillimeters": 5000000.0,
      "steps": "6200",
      "averageSpeedMillimetersPerSecond": 2777.78,
      "averagePaceSecondsPerMeter": 360.0,
      "averageHeartRateBeatsPerMinute": "148",
      "activeZoneMinutes": "30"
    },
    "exerciseMetadata": {
      "hasGps": true
    },
    "exerciseEvents": [
      {
        "eventTime": "2026-04-20T08:15:00Z",
        "eventUtcOffset": "0s",
        "exerciseEventType": "PAUSE"
      },
      {
        "eventTime": "2026-04-20T08:20:00Z",
        "eventUtcOffset": "0s",
        "exerciseEventType": "RESUME"
      }
    ],
    "splitSummaries": [
      {
        "startTime": "2026-04-20T08:00:00Z",
        "startUtcOffset": "0s",
        "endTime": "2026-04-20T08:15:00Z",
        "endUtcOffset": "0s",
        "splitType": "DISTANCE",
        "metricsSummary": {
          "distanceMillimeters": 2500000.0,
          "caloriesKcal": 190.0
        }
      }
    ]
  }
}

回應

{
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.devicesandservices.health.v4main.DataPoint",
    "name": "users/me/dataTypes/exercise/dataPoints/morning-trail-run-123456",
    "dataSource": {
      "recordingMethod": "ACTIVELY_MEASURED",
      "application": {
        "packageName": "com.example.workoutapp"
      },
      "platform": "GOOGLE_WEB_API"
    },
    "exercise": {
      "interval": {
        "startTime": "2026-04-20T08:00:00Z",
        "startUtcOffset": "0s",
        "endTime": "2026-04-20T08:35:00Z",
        "endUtcOffset": "0s"
      },
      "exerciseType": "RUNNING",
      "displayName": "Morning Trail Run",
      "activeDuration": "1800s",
      "metricsSummary": {
        "caloriesKcal": 380.0,
        "distanceMillimeters": 5000000.0,
        "steps": "6200",
        "averageSpeedMillimetersPerSecond": 2777.78,
        "averagePaceSecondsPerMeter": 360.0,
        "averageHeartRateBeatsPerMinute": "148",
        "activeZoneMinutes": "30"
      },
      "exerciseMetadata": {
        "hasGps": true
      },
      "exerciseEvents": [
        {
          "eventTime": "2026-04-20T08:15:00Z",
          "eventUtcOffset": "0s",
          "exerciseEventType": "PAUSE"
        },
        {
          "eventTime": "2026-04-20T08:20:00Z",
          "eventUtcOffset": "0s",
          "exerciseEventType": "RESUME"
        }
      ],
      "splitSummaries": [
        {
          "startTime": "2026-04-20T08:00:00Z",
          "startUtcOffset": "0s",
          "endTime": "2026-04-20T08:15:00Z",
          "endUtcOffset": "0s",
          "activeDuration": "900s",
          "splitType": "DISTANCE",
          "metricsSummary": {
            "distanceMillimeters": 2500000.0,
            "caloriesKcal": 190.0
          }
        }
      ]
    }
  }
}

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

回應

HTTP 酬載,其中包含 Content-Type: application/tcx+xml 和標頭,指示瀏覽器儲存檔案。

<?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

如果授權標頭缺少必要範圍,Google Health API 會傳回授權錯誤。

規範

將運動追蹤功能整合至應用程式時,請遵循下列設計和實作規範。

有效時間與總時間

如要計算速度或配速指標,請一律使用 activeDuration,而非 startTimeendTime 之間的差異。這樣可避免暫停的間隔扭曲指標。

舉例來說,如果使用者在 08:00 開始運動,並在 08:35 結束,運動的總經過時間為 2,100 秒。如果使用者暫停運動 5 分鐘 (300 秒),請將 activeDuration 設為 "1800s" (2,100 - 300)。API 會使用活動時間計算平均值,並將總距離除以 1,800 秒,而非 2,100 秒。

提早要求位置資訊

如果應用程式會繪製運動路線地圖,除了活動和健身範圍外,請一併要求位置存取權和 Google 健康 location 範圍。向使用者說明應用程式在查看 GPS 運動時需要位置範圍的原因。

當應用程式要求位置資訊範圍 (https://www.googleapis.com/auth/googlehealth.location.readonly) 時,Google OAuth 會向使用者顯示同意提示。向使用者說明,這項權限是為了顯示路線疊加層和匯出 GPS 軌跡檔案 (TCX) 所需。如果使用者授予活動範圍權限,但拒絕位置存取權,exportExerciseTcx 會傳回授權錯誤,但您仍可在 metricsSummary 中存取工作階段匯總資料。

使用 Webhook 進行即時同步

訂閱 exercise 資料類型,以便在有新的運動資料時,透過 Webhook 通知後端。這樣就能即時觸發運動後體驗。

伺服器收到 Webhook 通知時,通知會包含 healthUserId 和運動的特定實際時間間隔。伺服器應以非同步方式處理通知,然後從 /users/me/dataTypes/exercise/dataPoints 端點要求新的 exercise 資料點。如要瞭解如何設定訂閱項目,請參閱Webhook 訂閱項目

維持一致的指標

為提供完整的訓練體驗,應用程式必須同步處理高頻率的遙測資料點,以及整體 exercise 訓練課程。確保使用者的每日總數、歷史趨勢和詳細圖表保持完全一致。

同步處理遙測和工作階段 (寫入路徑)

將完成的訓練活動匯入或寫入 Google Health API 時,請實作多步驟寫入模式:

  1. 撰寫工作階段:將資料點發布至 POST /users/me/dataTypes/exercise/dataPoints,歸檔摘要事件。
  2. 寫入時間序列間隔:同時將運動期間記錄的精細資料點 (例如每分鐘步數或熱量消耗間隔) 寫入各自的集合:
    • POST /users/me/dataTypes/steps/dataPoints
    • POST /users/me/dataTypes/active-energy-burned/dataPoints
    • POST /users/me/dataTypes/heart-rate/dataPoints

查詢圖表的詳細資料 (讀取路徑)

在為特定運動工作階段算繪過往運動資訊主頁或成效圖表時,請使用工作階段的時間範圍查詢精細的遙測資料:

  1. 查詢訓練摘要:呼叫 /users/me/dataTypes/exercise/dataPoints 擷取整體訓練詳細資料和最終 metricsSummary
  2. 擷取圖表指標:檢查運動的 interval.startTimeinterval.endTime。針對該特定時間範圍,對遙測資料收集進行次要 GET 呼叫:
    • GET /users/me/dataTypes/heart-rate/dataPoints?startTime=2026-04-20T08:00:00Z&endTime=2026-04-20T08:35:00Z
  3. 擷取 GPS 路線:如果工作階段的中繼資料指出有 GPS 資料 (exerciseMetadata.hasGpstrue),請叫用 exportExerciseTcx 輔助方法下載路線座標。