Desenvolver experiências de treino com a API Google Health

A API Google Health rastreia as sessões de treino e o histórico de exercícios do usuário usando o tipo de dados de sessão exercise. Uma sessão funciona como um contêiner que agrupa metadados de atividade, eventos de pausa e retomada, voltas ou divisões e métricas de resumo.

Entenda como ler, gravar e estruturar treinos no seu aplicativo para oferecer a melhor experiência aos usuários.

Tipos de dados compatíveis

A API oferece suporte ao seguinte tipo de dados para rastrear treinos e sessões de atividade:

Tabela: tipos de dados de treinos da API Google Health
Tipo de dados
  dataType
  filter parâmetro
Tipo de registro
Operações disponíveis
Escopo Suporte a webhook
Suporte a zeros verdadeiros
Exercício
  exercise
  exercise
Sessão list, get, reconcile, create, update, batchDelete .activity_and_fitness.readonly
.activity_and_fitness.writeonly

Embora as sessões de treino usem o tipo de dados exercise como um contêiner, os trackers de treino típicos gravam e leem telemetria detalhada e de alta frequência durante a sessão. Essas medições (como frequência cardíaca ou contagem de passos) precisam ser lidas ou gravadas usando os próprios tipos de dados.

A tabela a seguir mapeia os campos dentro do objeto metricsSummary do tipo de dados exercise para os tipos de dados de telemetria brutos correspondentes da API Google Health:

Campo de resumo (metricsSummary) Nome do tipo de dados de telemetria intradiária ID do tipo de dados de telemetria da API
caloriesKcal Calorias queimadas em atividade active-energy-burned
distanceMillimeters Distância distance
steps Etapas steps
averageHeartRateBeatsPerMinute Frequência cardíaca heart-rate
activeZoneMinutes Minutos na faixa ativa active-zone-minutes

As seções a seguir fornecem detalhes técnicos para o tipo de dados exercise, incluindo exemplos de representação REST, processamento de rotas de GPS e diretrizes de integração.

Sessões de treino

Grave atividades ou treinos diários como pontos de dados de sessão exercise. Cada ponto de dados descreve a sessão geral, detalha os intervalos de eventos (como ações de pausa e retomada) e fornece métricas de resumo (como distância total, etapas e frequência cardíaca média).

Atributos de sessão

Ao estruturar um ponto de dados de exercício, verifique os seguintes componentes principais:

  • Horário da sessão (interval): o horário de início e término da sessão de treino geral, além dos deslocamentos de fuso horário ativos nesses pontos.
  • Tipo de atividade (exerciseType): a categoria de atividade realizada (como RUNNING, WALKING, BIKING ou AEROBIC_WORKOUT). Especifique o tipo exato de treinamento físico.
  • Nome de exibição (displayName): um nome fácil de usar para a sessão de treino (por exemplo, "Corrida de trilha à tarde").
  • Duração ativa (activeDuration): o tempo ativo real do treino, excluindo intervalos pausados. A formatação padrão usa o formato Duration (por exemplo, "1800s").

Métricas de resumo

O objeto aninhado metricsSummary contém métricas totais e médias calculadas durante toda a duração da sessão de exercícios:

  • caloriesKcal: total de calorias ativas queimadas durante o treino, medidas em quilocalorias (kcal).
  • distanceMillimeters: distância total percorrida, medida em milímetros para manter alta precisão em todas as unidades.
  • steps: total de passos dados durante o exercício.
  • averageHeartRateBeatsPerMinute: frequência cardíaca média do usuário durante os minutos de atividade da sessão.
  • activeZoneMinutes: minutos cumulativos na faixa ativa ganhos durante o treino.
  • averageSpeedMillimetersPerSecond: velocidade média de movimento em milímetros por segundo.
  • averagePaceSecondsPerMeter: ritmo médio durante os minutos de atividade da sessão, medido em segundos por metro.
  • elevationGainMillimeters: ganho de elevação total durante a sessão.

Voltas e divisões

Para treinos que envolvem voltas (como corridas de pista ou natação em piscina), use splitSummaries.

Cada divisão contém:

  • Um startTime e endTime específicos.
  • Uma activeDuration que representa o tempo real da volta.
  • Um metricsSummary com escopo apenas para esse segmento.
  • Um splitType para definir os limites de divisão (como DISTANCE, DURATION ou MANUAL).

Eventos de exercício

Para calcular com precisão a duração ativa, rastreie as transições de estado (como eventos de pausa manual ou automática) usando exerciseEvents.

Cada evento contém o carimbo de data/hora (eventTime) e o tipo:

  • START / STOP: indica carimbos de data/hora de limite de quando o usuário iniciou ou interrompeu explicitamente o registro.
  • PAUSE / RESUME: indica quando a sessão foi pausada ou retomada manualmente.
  • AUTO_PAUSE / AUTO_RESUME: indica pausas/retomadas automáticas orientadas por sensor.

Gravar uma sessão de treino

Para criar, atualizar ou importar uma sessão de treino, grave um ponto de dados na coleção de tipos de dados exercise. Use o endpoint de pontos de dados create.

Exemplo de representação REST

O exemplo a seguir mostra como gravar uma sessão de treino usando um método POST:

Solicitação

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

Resposta

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

Rotas de GPS e rastreamento de localização

A API salva resumos básicos de sessão diretamente no ponto de dados exercise, mas processa o histórico de localização detalhado e as coordenadas de rota de GPS como um fluxo separado.

Para fazer o download dos dados detalhados da rota de uma sessão ao ar livre, chame o método personalizado exportExerciseTcx. Esse endpoint retorna a rota no formato Training Center XML (TCX) padrão do setor.

Exportar rota de GPS

Solicitação

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

Resposta

Um payload HTTP com Content-Type: application/tcx+xml e cabeçalhos que instruem o navegador a salvar o arquivo.

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

Escopos e localização necessários

Para usar o recurso Rotas de GPS e rastreamento de localização, seu app precisa solicitar os seguintes escopos do OAuth:

  • Ler: https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly
  • Gravar: https://www.googleapis.com/auth/googlehealth.activity_and_fitness.writeonly
  • Ler: https://www.googleapis.com/auth/googlehealth.location.readonly

Diretrizes

Ao integrar o rastreamento de treinos ao seu app, siga estas diretrizes de design e implementação.

Duração ativa versus total

Para calcular métricas de velocidade ou ritmo, sempre use activeDuration em vez da diferença entre startTime e endTime. Isso evita que intervalos pausados distorçam suas métricas.

Por exemplo, se um usuário iniciar um treino às 8h e terminar às 8h35, o treino terá uma duração total de 2.100 segundos. Se o usuário pausou o treino por 5 minutos (300 segundos), defina activeDuration como "1800s" (2.100 - 300). A API usa a duração ativa para calcular médias, dividindo a distância total por 1.800 segundos em vez de 2.100.

Solicitar localização cedo

Se o app mapeia rotas de treino, solicite permissões de localização e o escopo location do Google Health, além do escopo de atividade e condicionamento físico. Explique aos usuários por que o app exige o escopo de localização ao analisar exercícios de GPS.

Quando o app solicita o escopo de localização (https://www.googleapis.com/auth/googlehealth.location.readonly), o Google OAuth mostra uma solicitação de consentimento ao usuário. Explique aos usuários que essa permissão é necessária para renderizar sobreposições de rota e exportar arquivos de faixa de GPS (TCX). Se um usuário conceder o escopo de atividade, mas negar a permissão de localização, exportExerciseTcx vai retornar um erro de autorização, embora ainda seja possível acessar agregados de sessão em metricsSummary.

Sincronização em tempo real usando webhooks

Inscreva-se no tipo de dados exercise para notificar seu back-end usando webhooks quando novos dados de treino ficarem disponíveis. Isso permite acionar experiências pós-treino em tempo real.

Quando o servidor recebe uma notificação de webhook, ela contém o healthUserId e o intervalo de tempo físico específico do treino. O servidor precisa processar a notificação de forma assíncrona e, em seguida, solicitar o novo exercise ponto de dados do /users/me/dataTypes/exercise/dataPoints endpoint. Para detalhes sobre como configurar assinaturas, consulte Assinaturas de webhook.

Manter métricas consistentes

Para oferecer uma sensação após o treino completa, seu app precisa sincronizar pontos de dados de telemetria de alta frequência com a sessão exercise geral. Isso garante que os totais diários, as tendências históricas e os gráficos de detalhes do usuário permaneçam totalmente alinhados.

Sincronizar telemetria e sessões (caminho de gravação)

Ao importar ou gravar um treino concluído na API Google Health, implemente um padrão de gravação de várias etapas:

  1. Grave a sessão: registre o evento de resumo postando um ponto de dados em POST /users/me/dataTypes/exercise/dataPoints.
  2. Grave intervalos de série temporal: grave simultaneamente os pontos de dados granulares registrados durante o treino (por exemplo, etapas por minuto ou intervalos de queima de calorias) nas respectivas coleções:
    • POST /users/me/dataTypes/steps/dataPoints
    • POST /users/me/dataTypes/active-energy-burned/dataPoints
    • POST /users/me/dataTypes/heart-rate/dataPoints

Consultar dados detalhados para gráficos (caminho de leitura)

Ao renderizar painéis de treino históricos ou gráficos de desempenho para uma sessão de treino específica, consulte a telemetria granular usando a janela de tempo da sessão:

  1. Consulte os resumos da sessão: chame /users/me/dataTypes/exercise/dataPoints para buscar os detalhes gerais do treino e o metricsSummary final.
  2. Busque métricas de gráfico: inspecione interval.startTime e interval.endTime do treino. Faça chamadas GET secundárias para as coleções de telemetria dessa janela de tempo específica:
    • GET /users/me/dataTypes/heart-rate/dataPoints?startTime=2026-04-20T08:00:00Z&endTime=2026-04-20T08:35:00Z
  3. Busque rotas de GPS: se os metadados da sessão indicarem que os dados de GPS estão presentes (exerciseMetadata.hasGps é true), invoque o método auxiliar exportExerciseTcx para fazer o download das coordenadas da rota.