Sessões

Na Conexão Saúde, uma sessão é um intervalo de tempo em que o usuário realiza uma atividade. Os tipos de dados SleepSessionRecord e ExerciseSessionRecord são sessões.

As sessões permitem que os usuários meçam a performance com base no tempo durante um período, como frequência cardíaca contínua ou dados de local.

As sessões de ExerciseSessionRecord incluem várias atividades, desde corrida até badminton.

As sessões SleepSessionRecord contêm dados que registram os estágios do sono, como AWAKE, SLEEPING e DEEP.

Dados de subtipo são aqueles que "pertencem" a uma sessão e que só são significativos quando lidos com uma sessão mãe, por exemplo, estágio de sono, segmento de exercício.

Dados associados são dados de Record que podem ser lidos separadamente ou com outras sessões, como passos, frequência cardíaca.

Diretrizes gerais

Confira algumas práticas recomendadas para trabalhar com sessões na Conexão Saúde.

  • Use as sessões para adicionar dados de um treino, de uma atividade específica ou de sono:
suspend fun writeExerciseSession(healthConnectClient: HealthConnectClient) {
    healthConnectClient.insertRecords(
        listOf(
            ExerciseSessionRecord(
                startTime = Instant.parse("2022-05-10T10:00:00.000Z"),
                startZoneOffset = ZoneOffset.of("-08:00"),
                endTime = Instant.parse("2022-05-10T11:00:00.000Z"),
                endZoneOffset = ZoneOffset.of("-08:00"),
                exerciseType = ExerciseSessionRecord.ExerciseType.WALKING,
                title = "My Walk"
            ),
            StepsRecord(
                startTime = Instant.parse("2022-05-10T10:00:00.000Z"),
                startZoneOffset = ZoneOffset.of("-08:00"),
                endTime = Instant.parse("2022-05-10T10:30:00.000Z"),
                endZoneOffset = ZoneOffset.of("-08:00"),
                count = 2800
            ),
StepsRecord(
                startTime = Instant.parse("2022-05-10T10:30:00.000Z"),
                startZoneOffset = ZoneOffset.of("-08:00"),
                endTime = Instant.parse("2022-05-10T11:00:00.000Z"),
                endZoneOffset = ZoneOffset.of("-08:00"),
                count = 3200
            ),  
        )
    )
}
  • As sessões não são usadas para medições gerais, como contagens diárias de passos.
  • Os dados de subtipo não contêm um UID, mas os dados associados têm UIDs distintos.
  • Os dados de subtipo precisam estar alinhados em uma sessão com carimbos de data/hora sequenciais que não se sobrepõem. No entanto, lacunas são permitidas.
  • As sessões são úteis quando o usuário quer que os dados sejam associados e monitorados como parte de uma sessão, em vez de registrados continuamente.

Sessões de sono

Você pode ler ou gravar dados de sono na Conexão Saúde. Os dados de sono são mostrados como uma sessão e podem ser divididos em oito estágios distintos de sono:

  • UNKNOWN: não especificado ou desconhecido se o usuário estiver dormindo.
  • AWAKE: o usuário está acordado durante o período de um ciclo de sono. Não é registrado durante o dia.
  • SLEEPING: descrição de sono genérica ou não granular.
  • OUT_OF_BED: o usuário sai da cama no meio de uma sessão de sono.
  • AWAKE_IN_BED: o usuário está acordado na cama.
  • LIGHT: o usuário está em um ciclo de sono leve.
  • DEEP: o usuário está em um ciclo de sono profundo.
  • REM: o usuário está em um ciclo de sono REM.

Esses valores representam o tipo de sono de um usuário dentro de um período. Gravar os estágios do sono é opcional. Recomendamos salvar, se possível.

Gravar sessões com ou sem estágios do sono

O tipo de dados SleepSessionRecord têm duas partes:

  1. A sessão geral, que abrange toda a duração do sono.
  2. Estágios individuais durante a sessão de sono, como sono leve ou profundo.

Confira como inserir uma sessão de sono sem estágios:

      SleepSessionRecord(
        title = "weekend sleep",
        startTime = startTime,
        endTime = endTime,
        startZoneOffset = ZoneOffset.UTC,
        endZoneOffset = ZoneOffset.UTC,
      )

Confira como adicionar estágios que abrangem todo o período de uma sessão de sono:

val stages = listOf(
    SleepSessionRecord.Stage(
        startTime = START_TIME
        endTime = END_TIME,
        stage = SleepSessionRecord.STAGE_TYPE_SLEEPING,
    )
)

SleepSessionRecord(
        title = "weekend sleep",
        startTime = START_TIME,
        endTime = END_TIME,
        startZoneOffset = START_ZONE_OFFSET,
        endZoneOffset = END_ZONE_OFFSET,
        stages = stages,
      )
  }

Ler uma sessão de sono

Para cada sessão de sono retornada, verifique se os dados do estágio de sono também estão presentes:

suspend fun readSleepSessions(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    val response =
        healthConnectClient.readRecords(
            ReadRecordsRequest(
                SleepSessionRecord::class,
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
            )
        )
    for (sleepRecord in response.records) {
        // Retrieve relevant sleep stages from each sleep record
        val sleepStages = sleepRecord.stages
    }
}

Excluir uma sessão de sono

Saiba como excluir uma sessão. Neste exemplo, usamos uma sessão de sono:

suspend fun deleteSleepSession(
    healthConnectClient: HealthConnectClient,
    sleepRecord: SleepSessionRecord,
) {
    val timeRangeFilter = TimeRangeFilter.between(sleepRecord.startTime, sleepRecord.endTime)
    healthConnectClient.deleteRecords(SleepSessionRecord::class, timeRangeFilter)
}

Sessões de exercícios

As sessões de exercícios podem incluir várias atividades, de corrida a badminton.

Gravar sessões de exercícios

Confira como criar uma solicitação de inserção que inclui uma sessão:

suspend fun writeExerciseSession(healthConnectClient: HealthConnectClient) {
    healthConnectClient.insertRecords(
        listOf(
            ExerciseSessionRecord(
                startTime = START_TIME,
                startZoneOffset = START_ZONE_OFFSET,
                endTime = END_TIME,
                endZoneOffset = END_ZONE_OFFSET,
                exerciseType = ExerciseSessionRecord.ExerciseType.RUNNING,
                title = "My Run"
            ),
            DistanceRecord(
                startTime = START_TIME,
                startZoneOffset = START_ZONE_OFFSET,
                endTime = END_TIME,
                endZoneOffset = END_ZONE_OFFSET,
                distance = 5000.meters
            ),
            // ... other records
        )
    )
}

No exemplo anterior, um registro é adicionado para a Distance, que abrange toda a duração da sessão, mas os dados podem ser adicionados com granularidades distintas.

Se o app tivesse medido a distância com frequência durante a corrida, outra abordagem possível seria incluir vários registros, cada um representando a distância percorrida em uma parte do exercício.

Ler uma sessão de exercícios

Confira um exemplo de como ler uma sessão de exercícios:

suspend fun readExerciseSessions(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    val response =
        healthConnectClient.readRecords(
            ReadRecordsRequest(
                ExerciseSessionRecord::class,
                timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
            )
        )
    for (exerciseRecord in response.records) {
        // Process each exercise record
        // Optionally pull in with other data sources of the same time range.
        val distanceRecord =
            healthConnectClient
                .readRecords(
                    ReadRecordsRequest(
                        DistanceRecord::class,
                        timeRangeFilter =
                            TimeRangeFilter.between(
                                exerciseRecord.startTime,
                                exerciseRecord.endTime
                            )
                    )
                )
                .records
    }
}

Gravar dados de subtipo

As sessões também podem ser compostas por dados de subtipo não obrigatórios, que fornecem mais informações para melhorar a sessão.

Por exemplo, as sessões de exercício podem incluir as classes ExerciseSegment, ExerciseLap e ExerciseRoute:

val segments = listOf(
  ExerciseSegment(
    startTime = Instant.parse("2022-01-02T10:10:10Z"),
    endTime = Instant.parse("2022-01-02T10:10:13Z"),
    segmentType = ActivitySegmentType.BENCH_PRESS,
    repetitions = 373
  )
)

val laps = listOf(
  ExerciseLap(
    startTime = Instant.parse("2022-01-02T10:10:10Z"),
    endTime = Instant.parse("2022-01-02T10:10:13Z"),
    length = 0.meters
  )
)

ExerciseSessionRecord(
  exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_CALISTHENICS,
    startTime = Instant.parse("2022-01-02T10:10:10Z"),
    endTime = Instant.parse("2022-01-02T10:10:13Z"),
  startZoneOffset = ZoneOffset.UTC,
  endZoneOffset = ZoneOffset.UTC,
  segments = segments,
  laps = laps,
  route = route
)

Excluir uma sessão de exercícios

Há duas maneiras de excluir uma sessão de exercícios:

  1. Por período.
  2. Por UID.

Confira como excluir dados de subtipo de acordo com o período:

suspend fun deleteExerciseSession(
    healthConnectClient: HealthConnectClient,
    exerciseRecord: ExerciseSessionRecord,
) {
    val timeRangeFilter = TimeRangeFilter.between(sleepRecord.startTime, sleepRecord.endTime)
    healthConnectClient.deleteRecords(SleepSessionRecord::class, timeRangeFilter)
    // delete the associated distance record
    healthConnectClient.deleteRecords(DistanceRecord::class, timeRangeFilter)
}

Também é possível excluir dados de subtipo pelo UID. No entanto, isso vai excluir apenas a sessão de exercícios, não os dados associados:

suspend fun deleteExerciseSession(
    healthConnectClient: HealthConnectClient,
    exerciseRecord: ExerciseSessionRecord,
) {
    healthConnectClient.deleteRecords(
        ExerciseSessionRecord::class,
        recordIdsList = listOf(exerciseRecord.metadata.id),
        clientRecordIdsList = emptyList()
    )
}