พัฒนาประสบการณ์การออกกำลังกายด้วย Google Health API

Google Health API จะติดตามเซสชันการออกกำลังกายและประวัติการออกกำลังกายของผู้ใช้โดยใช้ประเภทข้อมูลเซสชัน exercise เซสชันทำหน้าที่เป็นคอนเทนเนอร์ที่รวมข้อมูลเมตาของกิจกรรม เหตุการณ์หยุดชั่วคราวและกลับมาทำต่อ รอบหรือช่วงเวลา และเมตริกสรุป

ทำความเข้าใจวิธีอ่าน เขียน และจัดโครงสร้างการออกกำลังกายในแอปพลิเคชันเพื่อมอบประสบการณ์การใช้งานที่ดีที่สุดแก่ผู้ใช้

ประเภทข้อมูลที่รองรับ

API รองรับประเภทข้อมูลต่อไปนี้สำหรับการติดตามเซสชันการออกกำลังกายและกิจกรรม

ตาราง: ประเภทข้อมูลการออกกำลังกายของ Google Health API
ประเภทข้อมูล
  dataType
  filter พารามิเตอร์
ประเภทบันทึก
การดำเนินการที่ใช้ได้
ขอบเขต การรองรับWebhook
การรองรับค่า 0 จริง
การออกกำลังกาย
  exercise
  exercise
เซสชัน list, get, reconcile, create, update, batchDelete activity_and_fitness

แม้ว่าเซสชันการออกกำลังกายจะใช้ประเภทข้อมูล exercise เป็นคอนเทนเนอร์ แต่เครื่องมือติดตามการออกกำลังกายทั่วไปจะเขียนและอ่านข้อมูลการวัดและส่งข้อมูลโดยละเอียดที่มีความถี่สูงระหว่างเซสชัน ระบบจะต้องอ่านหรือเขียนการวัดเหล่านี้ (เช่น อัตราการเต้นของหัวใจหรือจำนวนก้าว) โดยใช้ประเภทข้อมูลที่เกี่ยวข้อง

ตารางต่อไปนี้แสดงการจับคู่ฟิลด์ภายในออบเจ็กต์ metricsSummary ของประเภทข้อมูล exercise กับประเภทข้อมูลการวัดและส่งข้อมูลดิบที่เกี่ยวข้องของ Google Health API

ฟิลด์สรุป (metricsSummary) ชื่อประเภทข้อมูลการวัดและส่งข้อมูลระหว่างวัน รหัสประเภทข้อมูลการวัดและส่งข้อมูลของ API
caloriesKcal พลังงานที่ใช้ไปขณะเคลื่อนไหวร่างกาย active-energy-burned
distanceMillimeters ระยะทาง distance
steps ขั้นตอน steps
averageHeartRateBeatsPerMinute อัตราการเต้นของหัวใจ heart-rate
activeZoneMinutes นาทีในโซนแอ็กทีฟ active-zone-minutes

ส่วนต่อไปนี้จะให้รายละเอียดทางเทคนิคสำหรับประเภทข้อมูล exercise ซึ่งรวมถึงตัวอย่างการแสดง REST, การจัดการเส้นทาง GPS และหลักเกณฑ์การผสานรวม

เซสชันการออกกำลังกาย

เขียนกิจกรรมหรือการออกกำลังกายประจำวันเป็นจุดข้อมูลเซสชัน exercise จุดข้อมูลแต่ละจุดจะอธิบายเซสชันโดยรวม รายละเอียดช่วงเวลาของเหตุการณ์ (เช่น การดำเนินการหยุดชั่วคราวและกลับมาทำต่อ) และระบุเมตริกสรุป (เช่น ระยะทางโดยรวม จำนวนก้าว และอัตราการเต้นของหัวใจเฉลี่ย)

แอตทริบิวต์เซสชัน

เมื่อจัดโครงสร้างจุดข้อมูลการออกกำลังกาย ให้ตรวจสอบคอมโพเนนต์หลักต่อไปนี้

  • เวลาเซสชัน (interval): เวลาเริ่มต้นและเวลาสิ้นสุดของเซสชันการออกกำลังกายโดยรวม รวมถึงออฟเซ็ตเขตเวลาที่ใช้งานอยู่ในช่วงเวลาดังกล่าว
  • ประเภทกิจกรรม (exerciseType): หมวดหมู่ของกิจกรรมที่ทำ (เช่น RUNNING, WALKING, BIKING หรือ AEROBIC_WORKOUT) ระบุประเภทการฝึกทางกายภาพที่แน่นอน
  • ชื่อที่แสดง (displayName): ชื่อที่เข้าใจง่ายสำหรับเซสชันการออกกำลังกาย (เช่น "การวิ่งเทรลช่วงบ่าย")
  • ระยะเวลาที่ใช้งาน (activeDuration): เวลาที่ใช้งานจริงของการออกกำลังกาย โดยไม่รวมช่วงเวลาที่หยุดชั่วคราว การจัดรูปแบบมาตรฐานใช้รูปแบบ Duration (เช่น "1800s")

เมตริกสรุป

ออบเจ็กต์ 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

ตัวอย่างการแสดง 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 ปลายทางนี้จะแสดงเส้นทางในรูปแบบ 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

การตอบกลับ

เพย์โหลด 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 เสมอแทนที่จะใช้ความแตกต่างระหว่าง startTime กับ endTime วิธีนี้จะป้องกันไม่ให้ช่วงเวลาที่หยุดชั่วคราวบิดเบือนเมตริก

ตัวอย่างเช่น หากผู้ใช้เริ่มออกกำลังกายเวลา 08:00 น. และสิ้นสุดเวลา 08:35 น. การออกกำลังกายจะมีระยะเวลาที่ผ่านไปทั้งหมด 2,100 วินาที หากผู้ใช้หยุดออกกำลังกายชั่วคราวเป็นเวลา 5 นาที (300 วินาที) ให้ตั้งค่า activeDuration เป็น "1800s" (2,100 - 300) API จะใช้ระยะเวลาที่ใช้งานเพื่อคำนวณค่าเฉลี่ย โดยหารระยะทางทั้งหมดด้วย 1,800 วินาทีแทนที่จะเป็น 2,100 วินาที

ขอตำแหน่งล่วงหน้า

หากแอปของคุณแสดงเส้นทางการออกกำลังกาย ให้ขอสิทธิ์เข้าถึงตำแหน่งและขอบเขต location ของ Google Health นอกเหนือจากขอบเขตกิจกรรมและการออกกำลังกาย อธิบายให้ผู้ใช้ทราบถึงสาเหตุที่แอปของคุณต้องใช้ขอบเขตตำแหน่งเมื่อตรวจสอบการออกกำลังกายด้วย GPS

เมื่อแอปของคุณขอขอบเขตตำแหน่ง (https://www.googleapis.com/auth/googlehealth.location.readonly) Google OAuth จะแสดงข้อความแจ้งความยินยอมแก่ผู้ใช้ อธิบายให้ผู้ใช้ทราบว่าจำเป็นต้องมีสิทธิ์นี้เพื่อแสดงภาพซ้อนทับเส้นทางและส่งออกไฟล์แทร็ก GPS (TCX) หากผู้ใช้ให้สิทธิ์เข้าถึงขอบเขตกิจกรรมแต่ปฏิเสธสิทธิ์เข้าถึงตำแหน่ง exportExerciseTcx จะแสดงข้อผิดพลาดในการให้สิทธิ์ แม้ว่าคุณจะยังเข้าถึงข้อมูลรวมของเซสชันใน metricsSummary ได้

ซิงค์แบบเรียลไทม์โดยใช้ Webhook

สมัครใช้บริการประเภทข้อมูล exercise เพื่อแจ้งให้แบ็กเอนด์ทราบโดยใช้ Webhook เมื่อมีข้อมูลการออกกำลังกายใหม่ ซึ่งจะช่วยให้คุณทริกเกอร์ประสบการณ์การใช้งานหลังการออกกำลังกายแบบเรียลไทม์ได้

เมื่อเซิร์ฟเวอร์ของคุณได้รับการแจ้งเตือน Webhook การแจ้งเตือนนั้นจะมี healthUserId และช่วงเวลาทางกายภาพที่เฉพาะเจาะจงของการออกกำลังกาย เซิร์ฟเวอร์ของคุณควรประมวลผลการแจ้งเตือนแบบไม่พร้อมกัน จากนั้นขอจุดข้อมูลใหม่ exerciseจากปลายทาง/users/me/dataTypes/exercise/dataPoints ดูรายละเอียดเกี่ยวกับวิธีตั้งค่าการสมัครใช้บริการได้ที่ การสมัครใช้บริการ 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.startTime และ interval.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.hasGps เป็น true) ให้เรียกใช้เมธอดตัวช่วย exportExerciseTcx เพื่อดาวน์โหลดพิกัดเส้นทาง