Google Health API を使用してワークアウト エクスペリエンスを開発する

Google Health API は、exercise セッション データ型を使用して、ユーザーのワークアウト セッションとエクササイズ履歴をトラッキングします。セッションは、アクティビティのメタデータ、一時停止と再開のイベント、ラップまたはスプリット、概要指標をバンドルするコンテナとして機能します。

ユーザーに最適なエクスペリエンスを提供するために、アプリでワークアウトを読み取り、書き込み、構造化する方法について説明します。

サポートされるデータタイプ

この API は、ワークアウトとアクティビティ セッションのトラッキングに次のデータ型をサポートしています。

表: Google Health API のワークアウト データ型
データ型
  dataType
  filter パラメータ
Record
type
利用可能な
オペレーション
範囲 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

以降のセクションでは、REST 表現の例、GPS ルートの処理、統合ガイドラインなど、exercise データ型の技術的な詳細について説明します。

ワークアウト セッション

毎日のアクティビティやワークアウトを exercise セッション データポイントとして書き込みます。各データポイントは、セッション全体を記述し、イベント間隔(一時停止や再開などのアクション)の詳細を示し、概要指標(総距離、歩数、平均心拍数など)を提供します。

セッション属性

エクササイズ データポイントを構造化するときは、次のコア コンポーネントを確認します。

  • セッション時間(interval: ワークアウト セッション全体の開始時間と終了時間、およびその時点で有効なタイムゾーン オフセット。
  • アクティビティの種類(exerciseType: 実行されたアクティビティのカテゴリ(RUNNINGWALKINGBIKINGAEROBIC_WORKOUT など)。正確な種類のトレーニングを指定します。
  • 表示名(displayName: ワークアウト セッションのわかりやすい名前(「午後のトレイル ラン」など)。
  • アクティブ時間(activeDuration: ワークアウトの実際の活動時間。一時停止したインターバルは除きます。標準の書式設定では、Duration 形式("1800s" など)を使用します。

サマリー指標

metricsSummary ネストされたオブジェクトには、エクササイズ セッションの全期間にわたって計算された合計と平均の指標が含まれます。

  • caloriesKcal: ワークアウト中に消費された総アクティブ消費カロリー。キロカロリー(kcal)で測定されます。
  • distanceMillimeters: 移動した総距離。単位間の精度を維持するため、ミリメートル単位で測定されます。
  • steps: エクササイズ中に歩いた歩数の合計。
  • averageHeartRateBeatsPerMinute: セッションのアクティブな時間帯のユーザーの平均心拍数。
  • activeZoneMinutes: ワークアウト中に獲得したアクティブ ゾーン時間の累積値。
  • averageSpeedMillimetersPerSecond: 平均移動速度(ミリメートル/秒)。
  • averagePaceSecondsPerMeter: セッションのアクティブな時間帯の平均ペース(メートルあたりの秒数)。
  • elevationGainMillimeters: セッション中の合計獲得標高。

ラップとスプリット

ラップを含むワークアウト(トラックでのランニングやプールでの水泳など)の場合は、splitSummaries を使用します。

各分割には次のものが含まれます。

  • 特定の startTimeendTime
  • 実際のラップタイムを表す activeDuration
  • そのセグメントのみにスコープ設定された metricsSummary
  • 分割境界を定義する splitTypeDISTANCEDURATIONMANUAL など)。

エクササイズ イベント

アクティブな期間を正確に計算するには、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

レスポンス

ブラウザにファイルを保存するよう指示する 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

必要なスコープが認可ヘッダーにない場合、Google Health API は認可エラーを返します。

ガイドライン

ワークアウト トラッキングをアプリに統合する際は、以下の設計と実装のガイドラインに沿ってください。

アクティブな期間と合計期間

速度またはペースの指標を計算するには、startTimeendTime の差ではなく、常に activeDuration を使用します。これにより、一時停止した間隔が指標を歪めるのを防ぐことができます。

たとえば、ユーザーが 08:00 にワークアウトを開始し、08:35 に終了した場合、ワークアウトの合計経過時間は 2,100 秒になります。ユーザーがワークアウトを 5 分(300 秒)一時停止した場合、activeDuration"1800s"(2,100 - 300)に設定します。この API では、アクティブな時間を使用して平均を計算します。総距離を 2,100 秒ではなく 1,800 秒で割ります。

位置情報を早めにリクエストする

アプリでワークアウト ルートをマッピングする場合は、アクティビティとフィットネスのスコープに加えて、位置情報の利用許可と Google Health の location スコープをリクエストします。GPS エクササイズの確認時にアプリが位置情報の範囲を必要とする理由をユーザーに説明します。

アプリが位置情報スコープ(https://www.googleapis.com/auth/googlehealth.location.readonly)をリクエストすると、Google OAuth はユーザーに同意プロンプトを表示します。この権限は、ルート オーバーレイのレンダリングと GPS トラック ファイル(TCX)のエクスポートに必要であることをユーザーに説明します。ユーザーがアクティビティ スコープを付与しても位置情報の利用許可を拒否した場合、exportExerciseTcx は承認エラーを返しますが、metricsSummary でセッション集計にアクセスすることはできます。

ウェブフックを使用したリアルタイム同期

exercise データ型を登録して、新しいワークアウト データが利用可能になったときに、ウェブフックを使用してバックエンドに通知します。これにより、ワークアウト後のエクスペリエンスをリアルタイムでトリガーできます。

サーバーが webhook 通知を受信すると、その通知には healthUserId とワークアウトの特定の物理時間間隔が含まれます。サーバーは通知を非同期で処理し、/users/me/dataTypes/exercise/dataPoints エンドポイントから新しい exercise データポイントをリクエストする必要があります。サブスクリプションの設定方法について詳しくは、Webhook サブスクリプションをご覧ください。

一貫性のある指標を維持する

完全なワークアウト/トレーニング体験を提供するには、アプリで exercise セッション全体とともに高頻度のテレメトリー データポイントを同期する必要があります。これにより、ユーザーの 1 日の合計、過去の傾向、詳細グラフが完全に一致します。

テレメトリーとセッションを同期する(書き込みパス)

完了したワークアウトを Google Health API にインポートまたは書き込む場合は、マルチステップ書き込みパターンを実装します。

  1. セッションを書き込む: POST /users/me/dataTypes/exercise/dataPoints にデータポイントを投稿して、概要イベントをファイルに保存します。
  2. 時系列間隔を書き込む: ワークアウト中に記録された詳細なデータポイント(1 分ごとの歩数や消費カロリーの間隔など)を、それぞれのコレクションに同時に書き込みます。
    • 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 ヘルパー メソッドを呼び出してルート座標をダウンロードします。