Tworzenie funkcji związanych z treningiem za pomocą interfejsu Google Health API

Interfejs Google Health API śledzi sesje treningowe i historię ćwiczeń użytkownika za pomocą typu danych sesji exercise. Sesja działa jako kontener, który łączy metadane aktywności, zdarzenia wstrzymania i wznowienia, okrążenia lub odcinki oraz podsumowujące dane.

Dowiedz się, jak odczytywać, zapisywać i strukturyzować treningi w aplikacji, aby zapewnić użytkownikom jak najlepsze wrażenia.

Obsługiwane typy danych

Interfejs API obsługuje ten typ danych do śledzenia treningów i sesji aktywności:

Tabela: typy danych treningowych interfejsu Google Health API
Typ danych
  dataType
  filter parametr
Typ rekordu
Dostępne
operacje
Zakres Obsługa webhooków
Obsługa prawdziwych zer
Ćwiczenie
  exercise
  exercise
Sesja list, get, reconcile, create, update, batchDelete .activity_and_fitness.readonly
.activity_and_fitness.writeonly

Sesje treningowe używają typu danych exercise jako kontenera, ale typowe trackery treningowe zapisują i odczytują szczegółowe dane telemetryczne o wysokiej częstotliwości podczas sesji. Te pomiary (np. tętno lub liczba kroków) muszą być odczytywane lub zapisywane za pomocą odpowiednich typów danych.

W tabeli poniżej przedstawiono mapowanie pól w obiekcie metricsSummary typu danych exercise na odpowiednie typy danych telemetrycznych interfejsu Google Health API:

Pole podsumowania (metricsSummary) Nazwa typu danych telemetrycznych w ciągu dnia Identyfikator typu danych telemetrycznych interfejsu API
caloriesKcal Spalone kalorie podczas aktywności active-energy-burned
distanceMillimeters Odległość distance
steps Kroki steps
averageHeartRateBeatsPerMinute Tętno heart-rate
activeZoneMinutes Aktywne minuty w strefie active-zone-minutes

W sekcjach poniżej znajdziesz szczegóły techniczne dotyczące typu danych exercise, w tym przykłady reprezentacji REST, obsługę trasy GPS i wytyczne dotyczące integracji.

Sesje treningowe

Zapisuj codzienne aktywności lub treningi jako punkty danych sesji exercise. Każdy punkt danych opisuje ogólną sesję, szczegóły przedziałów czasu zdarzeń (np. wstrzymania i wznowienia) oraz zawiera podsumowujące dane (np. łączny dystans, kroki i średnie tętno).

Atrybuty sesji

Podczas strukturyzowania punktu danych ćwiczeń sprawdź te podstawowe komponenty:

  • Czas sesji (interval): czas rozpoczęcia i zakończenia całej sesji treningowej oraz przesunięcia strefy czasowej aktywne w tych momentach.
  • Typ aktywności (exerciseType): kategoria wykonywanej aktywności (np. RUNNING, WALKING, BIKING lub AEROBIC_WORKOUT). Określ dokładny typ treningu fizycznego.
  • Nazwa wyświetlana (displayName): przyjazna dla użytkownika nazwa sesji treningowej (np. „Popołudniowy bieg po szlaku”).
  • Czas aktywności (activeDuration): rzeczywisty czas aktywności treningu, z wyłączeniem przerw. Standardowe formatowanie używa formatu Duration (np. "1800s").

Podsumowujące dane

Obiekt zagnieżdżony metricsSummary zawiera łączne i średnie dane obliczone na podstawie całego czasu trwania sesji ćwiczeń:

  • caloriesKcal: łączna liczba spalonych kalorii podczas treningu, mierzona w kilokaloriach (kcal).
  • distanceMillimeters: łączny pokonany dystans, mierzony w milimetrach, aby zachować wysoką precyzję w różnych jednostkach.
  • steps: łączna liczba kroków wykonanych podczas ćwiczenia.
  • averageHeartRateBeatsPerMinute: średnie tętno użytkownika podczas aktywnych minut sesji.
  • activeZoneMinutes: łączna liczba aktywnych minut w strefie uzyskanych podczas treningu.
  • averageSpeedMillimetersPerSecond: średnia prędkość ruchu w milimetrach na sekundę.
  • averagePaceSecondsPerMeter: średnie tempo podczas aktywnych minut sesji, mierzone w sekundach na metr.
  • elevationGainMillimeters: łączne przebyte przewyższenie podczas sesji.

Okrążenia i odcinki

W przypadku treningów, które obejmują okrążenia (np. biegi na bieżni lub pływanie w basenie), użyj splitSummaries.

Każdy odcinek zawiera:

  • konkretny startTime i endTime.
  • activeDuration reprezentujący rzeczywisty czas okrążenia.
  • metricsSummary obejmujący tylko ten segment.
  • splitType określający granice podziału (np. DISTANCE, DURATION lub MANUAL).

Ćwiczenia

Aby dokładnie obliczyć czas aktywności, śledź przejścia stanu (np. zdarzenia wstrzymania ręcznego lub automatycznego) za pomocą exerciseEvents.

Każde zdarzenie zawiera sygnaturę czasową (eventTime) i typ:

  • START / STOP: wskazuje sygnatury czasowe, kiedy użytkownik wyraźnie rozpoczął lub zakończył rejestrowanie.
  • PAUSE / RESUME: wskazuje, kiedy sesja została ręcznie wstrzymana lub wznowiona.
  • AUTO_PAUSE / AUTO_RESUME: wskazuje automatyczne wstrzymanie/wznowienie spowodowane przez czujnik.

Zapisywanie sesji treningowej

Aby utworzyć, zaktualizować lub zaimportować sesję treningową, zapisz punkt danych w kolekcji typu danych exercise. Użyj punktu końcowego create punktów danych.

Przykład reprezentacji REST

Poniższy przykład pokazuje, jak zapisać sesję treningową za pomocą metody POST:

Żądanie

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

Odpowiedź

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

Trasy GPS i śledzenie lokalizacji

Interfejs API zapisuje podstawowe podsumowania sesji bezpośrednio w punkcie danych exercise, ale szczegółową historię lokalizacji i współrzędne trasy GPS obsługuje jako osobny strumień.

Aby pobrać szczegółowe dane trasy sesji na świeżym powietrzu, wywołaj metodę niestandardową exportExerciseTcx. Ten punkt końcowy zwraca trasę w standardowym formacie Training Center XML (TCX).

Eksportowanie trasy GPS

Żądanie

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

Odpowiedź

Ładunek HTTP z Content-Type: application/tcx+xml i nagłówkami informującymi przeglądarkę o zapisaniu pliku.

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

Wymagane zakresy i lokalizacja

Aby korzystać z funkcji Trasy GPS i śledzenie lokalizacji, Twoja aplikacja musi poprosić o te zakresy OAuth:

  • Odczyt: https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly
  • Zapis: https://www.googleapis.com/auth/googlehealth.activity_and_fitness.writeonly
  • Odczyt: https://www.googleapis.com/auth/googlehealth.location.readonly

Wytyczne

Podczas integrowania śledzenia treningów z aplikacją postępuj zgodnie z tymi wytycznymi dotyczącymi projektowania i implementacji.

Czas aktywności a łączny czas trwania

Aby obliczyć dane dotyczące prędkości lub tempa, zawsze używaj activeDuration zamiast różnicy między startTime a endTime. Zapobiega to zniekształcaniu danych przez przerwy.

Jeśli na przykład użytkownik rozpocznie trening o 8:00 i zakończy go o 8:35, łączny czas trwania treningu wyniesie 2100 sekund. Jeśli użytkownik wstrzymał trening na 5 minut (300 sekund), ustaw activeDuration na "1800s" (2100 – 300). Interfejs API używa czasu aktywności do obliczania średnich, dzieląc łączny dystans przez 1800 sekund zamiast 2100.

Wcześniejsze żądanie lokalizacji

Jeśli Twoja aplikacja mapuje trasy treningowe, oprócz zakresu aktywności i sprawności poproś o uprawnienia do lokalizacji i zakres location Google Health. Wyjaśnij użytkownikom, dlaczego Twoja aplikacja wymaga zakresu lokalizacji podczas sprawdzania ćwiczeń GPS.

Gdy Twoja aplikacja poprosi o zakres lokalizacji (https://www.googleapis.com/auth/googlehealth.location.readonly), Google OAuth wyświetli użytkownikowi prośbę o zgodę. Wyjaśnij użytkownikom, że to uprawnienie jest niezbędne do renderowania nakładek trasy i eksportowania plików śladu GPS (TCX). Jeśli użytkownik przyzna zakres aktywności, ale odmówi dostępu do lokalizacji, exportExerciseTcx zwróci błąd autoryzacji, ale nadal będziesz mieć dostęp do agregatów sesji w metricsSummary.

Synchronizacja w czasie rzeczywistym za pomocą webhooków

Subskrybuj typ danych exercise, aby powiadamiać backend za pomocą webhooków, gdy pojawią się nowe dane treningowe. Dzięki temu możesz w czasie rzeczywistym wywoływać działania po treningu.

Gdy serwer otrzyma powiadomienie webhooka, będzie ono zawierać healthUserId i konkretny fizyczny przedział czasu treningu. Serwer powinien przetworzyć powiadomienie asynchronicznie, a następnie poprosić o nowy exercise punkt danych z /users/me/dataTypes/exercise/dataPoints punktu końcowego. Więcej informacji o konfigurowaniu subskrypcji znajdziesz w artykule Subskrypcje webhooków.

Utrzymywanie spójnych danych

Aby zapewnić pełną jakość treningu, Twoja aplikacja musi synchronizować punkty danych telemetrycznych o wysokiej częstotliwości wraz z ogólną sesją exercise. Dzięki temu dzienne sumy użytkownika, trendy historyczne i szczegółowe wykresy pozostaną w pełni zgodne.

Synchronizowanie danych telemetrycznych i sesji (ścieżka zapisu)

Podczas importowania lub zapisywania ukończonego treningu w interfejsie Google Health API zaimplementuj wieloetapowy wzorzec zapisu:

  1. Zapisz sesję: prześlij zdarzenie podsumowania, wysyłając punkt danych do POST /users/me/dataTypes/exercise/dataPoints.
  2. Zapisz przedziały czasu szeregów czasowych: jednocześnie zapisz szczegółowe punkty danych zarejestrowane podczas treningu (np. kroki co minutę lub przedziały spalonych kalorii) w odpowiednich kolekcjach:
    • POST /users/me/dataTypes/steps/dataPoints
    • POST /users/me/dataTypes/active-energy-burned/dataPoints
    • POST /users/me/dataTypes/heart-rate/dataPoints

Wysyłanie zapytań o szczegółowe dane na potrzeby wykresów (ścieżka odczytu)

Podczas renderowania historycznych paneli treningowych lub wykresów skuteczności dla konkretnej sesji treningowej wysyłaj zapytania o szczegółowe dane telemetryczne za pomocą okna czasowego sesji:

  1. Wysyłaj zapytania o podsumowania sesji: wywołaj /users/me/dataTypes/exercise/dataPoints, aby pobrać ogólne szczegóły treningu i końcowy metricsSummary.
  2. Pobierz dane wykresu: sprawdź interval.startTime i interval.endTime treningu. Wykonaj dodatkowe wywołania GET do kolekcji danych telemetrycznych dla tego konkretnego okna czasowego:
    • GET /users/me/dataTypes/heart-rate/dataPoints?startTime=2026-04-20T08:00:00Z&endTime=2026-04-20T08:35:00Z
  3. Pobierz trasy GPS: jeśli metadane sesji wskazują, że dane GPS są obecne (exerciseMetadata.hasGps ma wartość true), wywołaj metodę pomocniczą exportExerciseTcx, aby pobrać współrzędne trasy.