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

Interfejs Google Health API śledzi sesje treningowe użytkownika i historię ćwiczeń za pomocą exercisetypu danych sesji. Sesja działa jako kontener, który zawiera 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 o treningach w interfejsie Google Health API
Typ danych
  dataType
  filter parameter
Record
type
Dostępne
operacje
Zakres Webhook
support
Obsługa wartości zerowych
Ćwiczenia
  exercise
  exercise
Sesja list, get, reconcile, create, update, batchDelete activity_and_fitness

Sesje treningowe używają typu danych exercise jako kontenera, ale typowe urządzenia do śledzenia treningów 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 przy użyciu odpowiednich typów danych.

W tej tabeli znajdziesz 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 Energia spalona 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 kolejnych sekcjach znajdziesz szczegóły techniczne dotyczące typu danych exercise, w tym przykłady reprezentacji REST, obsługę trasy GPS i wskazówki dotyczące integracji.

Sesje treningowe

Zapisuj codzienne aktywności lub treningi jako exercise punkty danych sesji. Każdy punkt danych opisuje całą sesję, zawiera szczegółowe informacje o przedziałach zdarzeń (np. o działaniach związanych z pauzą i wznowieniem) oraz podaje podsumowujące dane (np. ogólny dystans, liczbę kroków i średnie tętno).

Atrybuty sesji

Podczas strukturyzowania punktu danych ćwiczenia sprawdź te podstawowe komponenty:

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

Podsumowanie danych

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

  • caloriesKcal: Łączna liczba aktywnych kalorii spalonych podczas treningu, mierzona w kilokaloriach (kcal).
  • distanceMillimeters: całkowity pokonany dystans w milimetrach, aby zachować wysoką precyzję w przypadku różnych jednostek.
  • 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 zdobytych podczas treningu.
  • averageSpeedMillimetersPerSecond: średnia prędkość ruchu w milimetrach na sekundę.
  • averagePaceSecondsPerMeter: średnie tempo podczas aktywnych minut sesji, mierzone w sekundach na metr.
  • elevationGainMillimeters: całkowite przebyte przewyższenie podczas sesji.

Okrążenia i odcinki

W przypadku treningów obejmujących okrążenia (np. bieganie po bieżni lub pływanie w basenie) użyj splitSummaries.

Każdy podział zawiera:

  • określonego startTimeendTime;
  • activeDuration – rzeczywisty czas okrążenia.
  • metricsSummary, która jest ograniczona tylko do tego segmentu.
  • splitType, aby zdefiniować granice podziału (np. DISTANCE, DURATION lub MANUAL).

Ćwiczenia

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

Każde zdarzenie zawiera znacznik czasu (eventTime) i typ:

  • START / STOP: sygnatury czasowe oznaczające moment, w którym użytkownik wyraźnie rozpoczął lub zakończył nagrywanie.
  • PAUSE / RESUME: wskazuje, kiedy sesja została ręcznie wstrzymana lub wznowiona.
  • AUTO_PAUSE / AUTO_RESUME: wskazuje automatyczne wstrzymanie lub wznowienie działania na podstawie danych z czujnika.

Zapisywanie sesji treningowej

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

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 traktuje jako osobny strumień.

Aby pobrać szczegółowe dane trasy sesji na zewnątrz, 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 nagłówkami Content-Type: application/tcx+xml i  , które nakazują przeglądarce zapisanie 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 odczytywać lub zapisywać dane dotyczące tras GPS i śledzenia lokalizacji, poproś o te zakresy OAuth w tokenie dostępu aplikacji:

  • Dostęp do odczytu: https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly
  • Uprawnienia do zapisu: https://www.googleapis.com/auth/googlehealth.activity_and_fitness.writeonly
  • Dostęp do odczytu: https://www.googleapis.com/auth/googlehealth.location.readonly

Jeśli w nagłówkach autoryzacji brakuje wymaganego zakresu, interfejs Google Health API zwraca błąd autoryzacji.

Wytyczne

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

Czas aktywności a łączny czas trwania

Aby obliczyć dane dotyczące szybkości lub tempa, zawsze używaj wartości activeDuration zamiast różnicy między startTimeendTime. Zapobiega to zniekształcaniu danych przez wstrzymane interwały.

Jeśli np. 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 wartość activeDuration na "1800s" (2100 – 300). Interfejs API używa aktywnego czasu trwania do obliczania średnich wartości, dzieląc całkowity dystans przez 1800 sekund zamiast 2100.

Wcześniejsze wysyłanie prośby o lokalizację

Jeśli aplikacja mapuje trasy treningów, 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ń z użyciem GPS.

Gdy aplikacja zażąda zakresu 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 tras i eksportowania plików śladów GPS (TCX). Jeśli użytkownik przyzna zakres aktywności, ale odmówi dostępu do lokalizacji, interfejs API zwróci błąd autoryzacji, ale nadal będzie można uzyskać dostęp do zagregowanych danych sesji w metricsSummary.exportExerciseTcx

Synchronizacja w czasie rzeczywistym za pomocą webhooków

Subskrybuj typ danych exercise, aby powiadamiać backend za pomocą webhooków, gdy pojawią się nowe dane treningu. Umożliwia to wywoływanie w czasie rzeczywistym funkcji po treningu.

Gdy serwer otrzyma powiadomienie webhook, będzie ono zawierać healthUserId i konkretny przedział czasu trwania treningu. Serwer powinien przetworzyć powiadomienie asynchronicznie, a następnie wysłać żądanie nowego punktu danych exercise do punktu końcowego /users/me/dataTypes/exercise/dataPoints. Szczegółowe informacje o konfigurowaniu subskrypcji znajdziesz w artykule Subskrypcje webhooków.

Utrzymywanie spójnych danych

Aby zapewnić jakość treningu, aplikacja musi synchronizować dane telemetryczne o wysokiej częstotliwości wraz z ogólną exercise sesją. Dzięki temu dzienne sumy, trendy historyczne i wykresy szczegółowe użytkownika 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 zastosuj wieloetapowy wzorzec zapisu:

  1. Zapisz sesję: prześlij zdarzenie podsumowujące, publikując punkt danych w usłudze POST /users/me/dataTypes/exercise/dataPoints.
  2. Zapisywanie przedziałów czasowych szeregów czasowych: równoczesne zapisywanie szczegółowych punktów danych zarejestrowanych podczas treningu (np. liczby kroków lub przedziałów spalania kalorii z dokładnością do minuty) w odpowiednich kolekcjach:
    • POST /users/me/dataTypes/steps/dataPoints
    • POST /users/me/dataTypes/active-energy-burned/dataPoints
    • POST /users/me/dataTypes/heart-rate/dataPoints

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

Podczas renderowania historycznych pulpitów treningowych lub wykresów wydajności dla konkretnej sesji treningowej wysyłaj zapytania o szczegółowe dane telemetryczne, korzystając z okna czasowego sesji:

  1. Wysyłanie zapytań o podsumowania sesji: wywołaj funkcję /users/me/dataTypes/exercise/dataPoints, aby pobrać ogólne szczegóły treningu i ostateczne metricsSummary.
  2. Pobieranie danych wykresu: sprawdź interval.startTimeinterval.endTime treningu. Wykonaj dodatkowe wywołania GET do kolekcji danych telemetrycznych w określonym przedziale czasu:
    • GET /users/me/dataTypes/heart-rate/dataPoints?startTime=2026-04-20T08:00:00Z&endTime=2026-04-20T08:35:00Z
  3. Pobieranie tras GPS: jeśli metadane sesji wskazują, że dane GPS są obecne (exerciseMetadata.hasGps to true), wywołaj metodę pomocniczą exportExerciseTcx, aby pobrać współrzędne trasy.