Mengembangkan Pengalaman Latihan Fisik dengan Google Health API

Google Health API melacak sesi latihan dan histori olahraga pengguna menggunakan jenis data sesi exercise. Sesi berfungsi sebagai penampung yang menggabungkan metadata aktivitas, peristiwa jeda dan lanjutkan, putaran atau split, dan metrik ringkasan.

Pahami cara membaca, menulis, dan menyusun latihan dalam aplikasi Anda untuk memberikan pengalaman terbaik bagi pengguna.

Jenis data yang didukung

API ini mendukung jenis data berikut untuk melacak sesi olahraga dan aktivitas:

Tabel: Jenis data Latihan Fisik Google Health API
Jenis data Operasi
yang tersedia
Cakupan
Latihan
dataType: exercise
filter parameter: exercise
Jenis data: Sesi

Perangkat yang kompatibel

list, get, reconcile, create, update, batchDelete .activity_and_fitness.readonly
.activity_and_fitness.writeonly

Meskipun sesi olahraga menggunakan jenis data exercise sebagai penampung, perangkat wearable juga mencatat telemetri frekuensi tinggi yang mendetail selama sesi. Di Google Health API, jenis data telemetri intraday terperinci ini bersifat hanya baca dan tidak dapat dibuat atau diubah secara langsung melalui endpoint REST-nya sendiri. Saat menulis sesi olahraga melalui REST API, teruskan metrik olahraga gabungan di dalam objek metricsSummary dari titik data exercise.

Tabel berikut memetakan kolom ringkasan di dalam exercise.metricsSummary ke jenis data telemetri intraday hanya baca yang sesuai, yang dapat Anda kueri untuk rentang waktu latihan tersebut:

Kolom ringkasan (metricsSummary) Nama jenis data telemetri intraday ID jenis data telemetri API (hanya baca) Kolom filter (?filter=) Cakupan OAuth baca yang diperlukan
caloriesKcal Energi Aktif yang Terbakar active-energy-burned active_energy_burned.interval.start_time activity_and_fitness.readonly
distanceMillimeters Jarak distance distance.interval.start_time activity_and_fitness.readonly
steps Langkah steps steps.interval.start_time activity_and_fitness.readonly
averageHeartRateBeatsPerMinute Detak Jantung heart-rate heart_rate.sample_time.physical_time health_metrics_and_measurements.readonly
activeZoneMinutes Menit Zona Aktif active-zone-minutes active_zone_minutes.interval.start_time activity_and_fitness.readonly

Bagian berikut memberikan detail teknis untuk jenis data exercise, termasuk contoh representasi REST, penanganan rute GPS, dan panduan integrasi.

Sesi olahraga

Tulis aktivitas atau olahraga harian sebagai titik data sesi exercise. Setiap titik data menjelaskan sesi secara keseluruhan, merinci interval peristiwa (seperti tindakan jeda dan lanjutkan), dan memberikan metrik ringkasan (seperti jarak keseluruhan, langkah, dan detak jantung rata-rata).

Atribut sesi

Saat menyusun titik data olahraga, verifikasi komponen inti berikut:

  • Waktu Sesi (interval): Waktu mulai dan waktu berakhir sesi latihan secara keseluruhan, beserta selisih zona waktu yang aktif pada titik tersebut.
  • Jenis Aktivitas (exerciseType): Kategori aktivitas yang dilakukan (seperti RUNNING, WALKING, BIKING, atau AEROBIC_WORKOUT). Tentukan jenis latihan fisik yang tepat.
  • Nama Tampilan (displayName): Nama yang mudah digunakan untuk sesi olahraga. Saat dibuat melalui REST API, server akan mengisi nama tampilan yang dilokalkan untuk exerciseType, seperti "Run" untuk RUNNING.
  • Durasi Aktif (activeDuration): Waktu aktif sebenarnya dari latihan, tidak termasuk interval yang dijeda. Pemformatan standar menggunakan format Duration (misalnya, "1800s"). Di server, activeDuration dihitung dari interval sesi dikurangi interval PAUSE/RESUME atau AUTO_PAUSE/AUTO_RESUME dalam exerciseEvents.

Metrik ringkasan

Objek bertingkat metricsSummary berisi metrik total dan rata-rata yang dihitung selama seluruh durasi sesi latihan:

  • caloriesKcal: Total kalori terbakar aktif selama latihan, diukur dalam kilokalori (kcal).
  • distanceMillimeters: Total jarak yang ditempuh, diukur dalam milimeter untuk mempertahankan presisi tinggi di seluruh unit.
  • steps: Total langkah yang diambil selama latihan.
  • averageHeartRateBeatsPerMinute: Detak jantung rata-rata pengguna selama menit aktif sesi.
  • activeZoneMinutes: Menit zona aktif kumulatif yang diperoleh selama latihan.
  • averageSpeedMillimetersPerSecond: Kecepatan gerakan rata-rata dalam milimeter per detik.
  • averagePaceSecondsPerMeter: Kecepatan rata-rata selama menit aktif sesi, diukur dalam detik per meter.
  • elevationGainMillimeters: Total elevasi naik selama sesi.

Putaran dan split

Untuk olahraga yang melibatkan putaran (seperti lari di trek atau berenang di kolam renang) yang disinkronkan dari perangkat yang didukung, splitSummaries mengelompokkan sesi berdasarkan putaran atau split.

Setiap pemisahan berisi:

  • startTime dan endTime tertentu.
  • activeDuration yang mewakili waktu lap sebenarnya.
  • metricsSummary yang dicakupkan hanya ke segmen tersebut.
  • splitType untuk menentukan batas bagian (seperti DISTANCE, DURATION, atau MANUAL).

Peristiwa latihan

Untuk menghitung durasi aktif secara akurat, lacak transisi status (seperti peristiwa jeda manual atau otomatis) menggunakan exerciseEvents.

Setiap peristiwa berisi stempel waktu (eventTime) dan jenis:

  • START / STOP: Menunjukkan stempel waktu batas saat pengguna secara eksplisit memulai atau menghentikan perekaman.
  • PAUSE / RESUME: Menunjukkan kapan sesi dijeda atau dilanjutkan secara manual.
  • AUTO_PAUSE / AUTO_RESUME: Menunjukkan jeda/lanjut otomatis yang didorong oleh sensor.

Menulis sesi latihan

Untuk membuat, memperbarui, atau mengimpor sesi olahraga, tulis titik data ke koleksi jenis data exercise. Gunakan endpoint create dataPoints.

Contoh representasi REST

Contoh berikut menunjukkan cara menulis sesi latihan menggunakan metode POST:

Permintaan

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"
      }
    ]
  }
}

Respons

{
  "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"
    }
  }
}

Rute GPS dan pelacakan lokasi

API ini menyimpan ringkasan sesi dasar langsung dalam titik data exercise, tetapi menangani histori lokasi mendetail dan koordinat rute GPS sebagai aliran data terpisah.

Untuk mendownload data rute mendetail untuk sesi luar ruangan, panggil metode kustom exportExerciseTcx. Endpoint ini menampilkan rute dalam format Training Center XML (TCX) standar industri.

Ekspor rute GPS

Permintaan

GET https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints/exercise-data-point-id:exportExerciseTcx?alt=media
Authorization: Bearer access-token

Respons

Payload HTTP dengan Content-Type: application/tcx+xml dan header yang menginstruksikan browser untuk menyimpan file.

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

Cakupan dan lokasi yang diperlukan

Untuk menggunakan fitur pelacakan lokasi dan rute GPS, aplikasi Anda harus meminta cakupan OAuth berikut:

  • Baca: https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly
  • Tulis: https://www.googleapis.com/auth/googlehealth.activity_and_fitness.writeonly
  • Baca: https://www.googleapis.com/auth/googlehealth.location.readonly

Panduan

Saat mengintegrasikan pelacakan olahraga ke dalam aplikasi, ikuti panduan desain dan implementasi ini.

Durasi aktif versus total durasi

Untuk menghitung metrik kecepatan atau laju, selalu gunakan activeDuration, bukan perbedaan antara startTime dan endTime. Tindakan ini mencegah interval yang dijeda mendistorsi metrik Anda.

Misalnya, jika pengguna memulai latihan pada pukul 08.00 dan selesai pada pukul 08.35, latihan tersebut memiliki total durasi berlalu 2.100 detik. Jika pengguna menjeda latihan selama 5 menit (300 detik) dan Anda menyertakan peristiwa PAUSE dan RESUME di exerciseEvents, durasi aktifnya adalah "1800s" (2.100 - 300). API menggunakan durasi aktif untuk menghitung rata-rata, dengan membagi total jarak dengan 1.800 detik, bukan 2.100.

Penghitungan kecepatan dan laju

Google Health API menggunakan formula standar untuk menghitung kecepatan dan laju:

  • Kecepatan = distance / time(hour)
  • Pace = time(seconds) / distance

Header Accept-Language yang ditentukan dalam permintaan menentukan satuan jarak.

Meminta lokasi lebih awal

Jika aplikasi Anda memetakan rute olahraga, minta izin akses lokasi dan cakupan location Google Health selain cakupan aktivitas dan kebugaran. Jelaskan kepada pengguna alasan aplikasi Anda memerlukan cakupan lokasi saat meninjau latihan GPS.

Saat aplikasi Anda meminta cakupan lokasi (https://www.googleapis.com/auth/googlehealth.location.readonly), Google OAuth akan menampilkan dialog izin kepada pengguna. Jelaskan kepada pengguna bahwa izin ini diperlukan untuk merender overlay rute dan mengekspor file pelacakan GPS (TCX). Jika pengguna memberikan cakupan aktivitas, tetapi menolak izin akses lokasi, exportExerciseTcx akan menampilkan error otorisasi, meskipun Anda masih dapat mengakses agregat sesi di metricsSummary.

Sinkronisasi real-time menggunakan webhook

Berlangganan ke jenis data exercise untuk memberi tahu backend Anda menggunakan webhook saat data olahraga baru tersedia. Hal ini memungkinkan Anda memicu pengalaman pasca-latihan secara real time.

Saat server Anda menerima notifikasi webhook, notifikasi tersebut berisi healthUserId dan interval waktu sipil (civilIso8601TimeInterval) dari latihan yang diperbarui. Server Anda harus segera mengonfirmasi notifikasi dengan 204 No Content, memproses payload secara asinkron, dan mengkueri endpoint exercise yang direkonsiliasi menggunakan filter exercise.interval.civil_start_time (perhatikan bahwa exercise hanya mendukung pemfilteran menurut 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"

Untuk mengetahui detail tentang cara menyiapkan langganan, lihat Langganan webhook.

Mempertahankan metrik yang konsisten

Untuk memberikan pengalaman olahraga yang lengkap, sertakan metrik ringkasan saat menulis sesi exercise dan buat kueri endpoint telemetri hanya baca menggunakan filter rentang waktu saat merender diagram detail.

Menulis metrik ringkasan latihan (jalur tulis)

Saat mengimpor atau menulis olahraga yang telah selesai ke Google Health API, sertakan metrik telemetri gabungan olahraga (steps, caloriesKcal, distanceMillimeters, averageHeartRateBeatsPerMinute, dan averagePaceSecondsPerMeter) di dalam objek metricsSummary dari titik data exercise:

  • POST https://health.googleapis.com/v4/users/me/dataTypes/exercise/dataPoints

Mengkueri data mendetail untuk diagram (jalur baca)

Untuk membuat dasbor atau diagram olahraga untuk sesi tertentu, buat kueri endpoint telemetri yang direkonsiliasi untuk rentang waktu olahraga tersebut:

  1. Ambil sesi latihan dari endpoint exercise menggunakan filter civil_start_time untuk mendapatkan interval dan 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"
  2. Gunakan interval.startTime dan interval.endTime sesi untuk mengkueri endpoint telemetri untuk rentang waktu fisik tersebut.

  3. Jika exerciseMetadata.hasGps adalah true, panggil exportExerciseTcx untuk mendownload koordinat rute.