Phát triển trải nghiệm tập luyện bằng Google Health API

Google Health API theo dõi các phiên tập luyện và nhật ký tập thể dục của người dùng bằng cách sử dụng kiểu dữ liệu phiên exercise. Phiên hoạt động đóng vai trò là một vùng chứa kết hợp siêu dữ liệu hoạt động, các sự kiện tạm dừng và tiếp tục, số vòng hoặc số lần chia và các chỉ số tóm tắt.

Tìm hiểu cách đọc, ghi và cấu trúc các bài tập trong ứng dụng để mang lại trải nghiệm tốt nhất cho người dùng.

Các loại dữ liệu được hỗ trợ

API này hỗ trợ kiểu dữ liệu sau đây để theo dõi các buổi tập luyện và hoạt động:

Bảng: Các loại dữ liệu bài tập của Google Health API
Loại dữ liệu
  dataType
  filter tham số
Loại
bản ghi
Các thao tác
có thể thực hiện
Phạm vi Hỗ trợ
webhook
Hỗ trợ
số 0 thực
Tập thể dục
  exercise
  exercise
Phiên list, get, reconcile, create, update, batchDelete activity_and_fitness

Mặc dù các phiên tập luyện sử dụng loại dữ liệu exercise làm vùng chứa, nhưng các trình theo dõi hoạt động tập luyện thông thường sẽ ghi và đọc dữ liệu đo từ xa chi tiết, có tần suất cao trong phiên. Bạn phải đọc hoặc ghi các phép đo này (chẳng hạn như nhịp tim hoặc số bước) bằng các kiểu dữ liệu tương ứng của riêng chúng.

Bảng sau đây liên kết các trường bên trong đối tượng metricsSummary của kiểu dữ liệu exercise với các kiểu dữ liệu đo từ xa thô tương ứng của Google Health API:

Trường tóm tắt (metricsSummary) Tên loại dữ liệu đo từ xa trong ngày Mã loại dữ liệu đo từ xa API
caloriesKcal Năng lượng hoạt động đã đốt cháy active-energy-burned
distanceMillimeters Khoảng cách distance
steps Các bước steps
averageHeartRateBeatsPerMinute Nhịp tim heart-rate
activeZoneMinutes Số phút hoạt động cho vùng nhịp tim active-zone-minutes

Các phần sau đây cung cấp thông tin kỹ thuật cho kiểu dữ liệu exercise, bao gồm các ví dụ về biểu thị REST, cách xử lý tuyến đường GPS và nguyên tắc tích hợp.

Phiên tập thể dục

Ghi các hoạt động hoặc bài tập hằng ngày dưới dạng các điểm dữ liệu của phiên exercise. Mỗi điểm dữ liệu mô tả phiên tổng thể, chi tiết khoảng thời gian diễn ra sự kiện (chẳng hạn như hành động tạm dừng và tiếp tục) và cung cấp các chỉ số tóm tắt (chẳng hạn như tổng khoảng cách, số bước và tần số tim trung bình).

Thuộc tính của phiên

Khi cấu trúc một điểm dữ liệu bài tập, hãy xác minh các thành phần cốt lõi sau:

  • Thời gian của phiên (interval): Thời gian bắt đầu và thời gian kết thúc của toàn bộ phiên tập luyện, cùng với độ lệch múi giờ hoạt động tại những thời điểm đó.
  • Loại hoạt động (exerciseType): Danh mục hoạt động đã thực hiện (chẳng hạn như RUNNING, WALKING, BIKING hoặc AEROBIC_WORKOUT). Hãy chỉ định chính xác loại hình tập luyện thể chất.
  • Tên hiển thị (displayName): Tên thân thiện với người dùng cho phiên tập luyện (ví dụ: "Chạy đường mòn buổi chiều").
  • Thời lượng hoạt động (activeDuration): Thời gian hoạt động thực tế của bài tập, không bao gồm các khoảng thời gian tạm dừng. Định dạng tiêu chuẩn sử dụng định dạng Duration (ví dụ: "1800s").

Các chỉ số tóm lược

Đối tượng lồng nhau metricsSummary chứa các chỉ số tổng và trung bình được tính trong toàn bộ thời lượng của phiên tập thể dục:

  • caloriesKcal: Tổng lượng calo đã đốt cháy trong quá trình tập luyện, được đo bằng kilocalories (kcal).
  • distanceMillimeters: Tổng quãng đường đã đi, được đo bằng milimet để duy trì độ chính xác cao trên các đơn vị.
  • steps: Tổng số bước đã thực hiện trong bài tập.
  • averageHeartRateBeatsPerMinute: Tần số tim trung bình của người dùng trong số phút hoạt động của phiên.
  • activeZoneMinutes: Tổng số phút hoạt động cho vùng nhịp tim đã đạt được trong quá trình tập luyện.
  • averageSpeedMillimetersPerSecond: Tốc độ di chuyển trung bình tính bằng milimet/giây.
  • averagePaceSecondsPerMeter: Tốc độ trung bình trong số phút hoạt động của phiên, được đo bằng giây/mét.
  • elevationGainMillimeters: Tổng mức tăng độ cao trong phiên.

Số vòng và thời gian chia vòng

Đối với các bài tập có liên quan đến số vòng (chẳng hạn như chạy trên đường chạy hoặc bơi trong hồ bơi), hãy sử dụng splitSummaries.

Mỗi phần chia nhỏ chứa:

  • Một startTimeendTime cụ thể.
  • activeDuration biểu thị thời gian vòng đua thực tế.
  • metricsSummary chỉ được giới hạn trong phân khúc đó.
  • Một splitType để xác định ranh giới phân chia (chẳng hạn như DISTANCE, DURATION hoặc MANUAL).

Sự kiện tập thể dục

Để tính toán chính xác thời lượng hoạt động, hãy theo dõi các quá trình chuyển đổi trạng thái (chẳng hạn như sự kiện tạm dừng thủ công hoặc tự động) bằng cách sử dụng exerciseEvents.

Mỗi sự kiện đều chứa dấu thời gian (eventTime) và loại:

  • START / STOP: Cho biết dấu thời gian ranh giới khi người dùng bắt đầu hoặc dừng ghi một cách rõ ràng.
  • PAUSE / RESUME: Cho biết thời điểm phiên được tạm dừng hoặc tiếp tục theo cách thủ công.
  • AUTO_PAUSE / AUTO_RESUME: Cho biết tính năng tự động tạm dừng/tiếp tục dựa trên cảm biến.

Ghi dữ liệu về một phiên tập luyện

Để tạo, cập nhật hoặc nhập một phiên tập luyện, hãy ghi một điểm dữ liệu vào tập hợp kiểu dữ liệu exercise. Sử dụng điểm dữ liệu create.

Ví dụ về biểu thị REST

Ví dụ sau đây minh hoạ cách ghi một phiên tập luyện bằng phương thức POST:

Yêu cầu

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

Phản hồi

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

Tuyến đường và tính năng theo dõi vị trí bằng GPS

API này lưu các bản tóm tắt phiên cơ bản ngay trong điểm dữ liệu exercise, nhưng xử lý nhật ký vị trí chi tiết và toạ độ tuyến đường GPS dưới dạng một luồng riêng biệt.

Để tải dữ liệu chi tiết về tuyến đường cho một phiên hoạt động ngoài trời, hãy gọi phương thức tuỳ chỉnh exportExerciseTcx. Điểm cuối này trả về tuyến đường ở định dạng XML Trung tâm đào tạo (TCX) theo tiêu chuẩn ngành.

Xuất tuyến đường GPS

Yêu cầu

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

Phản hồi

Một tải trọng HTTP có tiêu đề Content-Type: application/tcx+xml và hướng dẫn trình duyệt lưu tệp.

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

Phạm vi và vị trí bắt buộc

Để đọc hoặc ghi dữ liệu cho các tuyến đường GPS và tính năng theo dõi vị trí, hãy yêu cầu các phạm vi OAuth sau trong mã truy cập của ứng dụng:

  • Quyền đọc: https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly
  • Quyền ghi: https://www.googleapis.com/auth/googlehealth.activity_and_fitness.writeonly
  • Quyền đọc: https://www.googleapis.com/auth/googlehealth.location.readonly

Nếu tiêu đề uỷ quyền thiếu một phạm vi bắt buộc, thì Google Health API sẽ trả về lỗi uỷ quyền.

Nguyên tắc

Khi tích hợp tính năng theo dõi hoạt động tập luyện vào ứng dụng, hãy tuân thủ các nguyên tắc thiết kế và triển khai sau.

Thời lượng hoạt động so với tổng thời lượng

Để tính toán các chỉ số tốc độ hoặc nhịp độ, hãy luôn sử dụng activeDuration thay vì chênh lệch giữa startTimeendTime. Điều này giúp các khoảng thời gian tạm dừng không làm sai lệch các chỉ số của bạn.

Ví dụ: nếu người dùng bắt đầu tập thể dục lúc 8:00 và kết thúc lúc 8:35, thì tổng thời gian đã trôi qua của bài tập là 2.100 giây. Nếu người dùng tạm dừng bài tập trong 5 phút (300 giây), hãy đặt activeDuration thành "1800s" (2.100 – 300). API này sử dụng thời lượng hoạt động để tính toán giá trị trung bình, chia tổng khoảng cách cho 1.800 giây thay vì 2.100 giây.

Yêu cầu vị trí sớm

Nếu ứng dụng của bạn lập bản đồ tuyến đường tập luyện, hãy yêu cầu quyền truy cập vào thông tin vị trí và phạm vi Google Health location ngoài phạm vi hoạt động và thể dục. Giải thích cho người dùng lý do ứng dụng của bạn yêu cầu phạm vi vị trí khi xem lại các bài tập GPS.

Khi ứng dụng của bạn yêu cầu phạm vi vị trí (https://www.googleapis.com/auth/googlehealth.location.readonly), Google OAuth sẽ hiển thị lời nhắc đồng ý cho người dùng. Giải thích cho người dùng rằng quyền này là cần thiết để hiển thị lớp phủ tuyến đường và xuất tệp theo dõi GPS (TCX). Nếu người dùng cấp phạm vi hoạt động nhưng từ chối quyền truy cập thông tin vị trí, exportExerciseTcx sẽ trả về lỗi uỷ quyền, mặc dù bạn vẫn có thể truy cập vào các giá trị tổng hợp của phiên trong metricsSummary.

Đồng bộ hoá theo thời gian thực bằng webhook

Đăng ký loại dữ liệu exercise để thông báo cho phần phụ trợ của bạn bằng cách sử dụng webhook khi có dữ liệu tập luyện mới. Điều này cho phép bạn kích hoạt trải nghiệm sau khi tập luyện theo thời gian thực.

Khi máy chủ của bạn nhận được thông báo webhook, thông báo này sẽ chứa healthUserId và khoảng thời gian thực tế cụ thể của buổi tập. Máy chủ của bạn sẽ xử lý thông báo không đồng bộ, sau đó yêu cầu điểm dữ liệu exercise mới từ điểm cuối /users/me/dataTypes/exercise/dataPoints. Để biết thông tin chi tiết về cách thiết lập gói thuê bao, hãy xem phần Gói thuê bao webhook.

Duy trì các chỉ số nhất quán

Để mang đến trải nghiệm tập luyện trọn vẹn, ứng dụng của bạn phải đồng bộ hoá các điểm dữ liệu đo từ xa có tần suất cao cùng với phiên exercise tổng thể. Điều này đảm bảo rằng tổng số hằng ngày, xu hướng trong quá khứ và biểu đồ chi tiết của người dùng vẫn hoàn toàn nhất quán.

Đồng bộ hoá dữ liệu đo từ xa và phiên (đường dẫn ghi)

Khi nhập hoặc ghi một buổi tập đã hoàn thành vào Google Health API, hãy triển khai một mẫu ghi nhiều bước:

  1. Ghi phiên: Ghi lại sự kiện tóm tắt bằng cách đăng một điểm dữ liệu lên POST /users/me/dataTypes/exercise/dataPoints.
  2. Ghi các khoảng thời gian theo chuỗi thời gian: Đồng thời ghi các điểm dữ liệu chi tiết được ghi lại trong quá trình tập luyện (ví dụ: số bước hoặc khoảng thời gian đốt cháy calo theo từng phút) vào các tập hợp tương ứng:
    • POST /users/me/dataTypes/steps/dataPoints
    • POST /users/me/dataTypes/active-energy-burned/dataPoints
    • POST /users/me/dataTypes/heart-rate/dataPoints

Truy vấn dữ liệu chi tiết cho biểu đồ (đường dẫn đọc)

Khi kết xuất trang tổng quan về bài tập hoặc biểu đồ hiệu suất trước đây cho một phiên tập luyện cụ thể, hãy truy vấn dữ liệu đo từ xa chi tiết bằng cách sử dụng khung thời gian của phiên:

  1. Truy vấn bản tóm tắt phiên: Gọi /users/me/dataTypes/exercise/dataPoints để tìm nạp thông tin chi tiết chung về hoạt động tập luyện và metricsSummary cuối cùng.
  2. Tìm nạp các chỉ số biểu đồ: Kiểm tra interval.startTimeinterval.endTime của bài tập. Thực hiện các lệnh gọi GET thứ cấp đến các bộ sưu tập đo từ xa cho khoảng thời gian cụ thể đó:
    • GET /users/me/dataTypes/heart-rate/dataPoints?startTime=2026-04-20T08:00:00Z&endTime=2026-04-20T08:35:00Z
  3. Tìm nạp tuyến đường GPS: Nếu siêu dữ liệu của phiên cho biết có dữ liệu GPS (exerciseMetadata.hasGpstrue), hãy gọi phương thức trợ giúp exportExerciseTcx để tải toạ độ tuyến đường xuống.