Запись данных

Данное руководство совместимо с версией Health Connect 1.1.0-alpha12 .

В этом руководстве описан процесс записи или обновления данных в Health Connect.

Обработка нулевых значений

Некоторые типы данных, такие как количество шагов, пройденное расстояние или калории, могут иметь значение 0 Записывайте нулевые значения только в том случае, если это отражает фактическую бездеятельность пользователя во время ношения устройства. Не записывайте нулевые значения, если устройство не было надето, данные отсутствуют или батарея разрядилась. В таких случаях запись следует опустить, чтобы избежать искажения данных.

Настройка структуры данных

Перед записью данных необходимо сначала подготовить записи. Для более чем 50 типов данных существует своя структура. Более подробную информацию о доступных типах данных см. в справочнике Jetpack .

Основные записи

В Health Connect тип данных «Шаги» отображает количество шагов, сделанных пользователем между измерениями. Подсчет шагов — это распространенный показатель на платформах для здоровья, фитнеса и хорошего самочувствия.

В следующем примере показано, как задать данные о количестве шагов:

val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(15))

val stepsRecord = StepsRecord(
    count = 120,
    startTime = startTime,
    endTime = endTime,
    startZoneOffset = ZoneOffset.UTC,
    endZoneOffset = ZoneOffset.UTC,
    metadata = Metadata.autoRecorded(
        device = Device(type = Device.TYPE_WATCH)
    )
)

Записи с единицами измерения

Health Connect может хранить значения вместе с единицами измерения для обеспечения точности. Примером может служить обширный и всеобъемлющий тип данных «Питание» . Он включает в себя широкий спектр необязательных полей, содержащих информацию о питательных веществах, от общего количества углеводов до витаминов. Каждая точка данных представляет собой питательные вещества, которые потенциально могли быть потреблены в составе приема пищи или продукта питания.

В этом типе данных все питательные вещества представлены в единицах массы , а energy — в единицах энергии .

В следующем примере показано, как задать данные о пищевой ценности продукта для пользователя, который съел банан:

val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(1))

val banana = NutritionRecord(
    name = "banana",
    energy = 105.0.kilocalories,
    dietaryFiber = 3.1.grams,
    potassium = 0.422.grams,
    totalCarbohydrate = 27.0.grams,
    totalFat = 0.4.grams,
    saturatedFat = 0.1.grams,
    sodium = 0.001.grams,
    sugar = 14.0.grams,
    vitaminB6 = 0.0005.grams,
    vitaminC = 0.0103.grams,
    startTime = startTime,
    endTime = endTime,
    startZoneOffset = ZoneOffset.UTC,
    endZoneOffset = ZoneOffset.UTC,
    metadata = Metadata.manualEntry(
        device = Device(type = Device.TYPE_PHONE)
    )
)

Записи с данными серий

Health Connect может хранить список последовательных данных. Например, тип данных « Частота сердечных сокращений» содержит серию выборок сердцебиения, зафиксированных между измерениями.

В этом типе данных параметр samples представлен списком Heart Rate samples . Каждый образец содержит значение beatsPerMinute и значение time .

В следующем примере показано, как задать параметры для ряда данных о частоте сердечных сокращений:

val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(5))

val heartRateRecord = HeartRateRecord(
    startTime = startTime,
    startZoneOffset = ZoneOffset.UTC,
    endTime = endTime,
    endZoneOffset = ZoneOffset.UTC,
    // records 10 arbitrary data, to replace with actual data
    samples = List(10) { index ->
        HeartRateRecord.Sample(
            time = startTime + Duration.ofSeconds(index.toLong()),
            beatsPerMinute = 100 + index.toLong(),
        )
    },
    metadata = Metadata.autoRecorded(
        device = Device(type = Device.TYPE_WATCH)
    ))

Запросить у пользователя разрешения

После создания экземпляра клиента ваше приложение должно запросить у пользователя разрешения. Пользователи должны иметь возможность предоставлять или отклонять разрешения в любое время.

Для этого создайте набор разрешений для необходимых типов данных. Убедитесь, что разрешения в этом наборе сначала объявлены в вашем Android-манифесте.

// Create a set of permissions for required data types
val PERMISSIONS =
    setOf(
  HealthPermission.getReadPermission(HeartRateRecord::class),
  HealthPermission.getWritePermission(HeartRateRecord::class),
  HealthPermission.getReadPermission(StepsRecord::class),
  HealthPermission.getWritePermission(StepsRecord::class)
)

Используйте getGrantedPermissions , чтобы проверить, предоставлены ли вашему приложению уже необходимые разрешения. Если нет, используйте createRequestPermissionResultContract для запроса этих разрешений. После этого отобразится экран разрешений Health Connect.

// Create the permissions launcher
val requestPermissionActivityContract = PermissionController.createRequestPermissionResultContract()

val requestPermissions = registerForActivityResult(requestPermissionActivityContract) { granted ->
  if (granted.containsAll(PERMISSIONS)) {
    // Permissions successfully granted
  } else {
    // Lack of required permissions
  }
}

suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient) {
  val granted = healthConnectClient.permissionController.getGrantedPermissions()
  if (granted.containsAll(PERMISSIONS)) {
    // Permissions already granted; proceed with inserting or reading data
  } else {
    requestPermissions.launch(PERMISSIONS)
  }
}

Поскольку пользователи могут предоставлять или отзывать разрешения в любое время, вашему приложению необходимо периодически проверять наличие предоставленных разрешений и обрабатывать ситуации, когда разрешение утрачивается.

Запись данных

Один из распространенных рабочих процессов в Health Connect — это запись данных. Для добавления записей используйте insertRecords .

В следующем примере показано, как записывать данные, включая количество шагов:

suspend fun insertSteps(healthConnectClient: HealthConnectClient) {
    val endTime = Instant.now()
    val startTime = endTime.minus(Duration.ofMinutes(5))
    try {
        val stepsRecord = StepsRecord(
            count = 120,
            startTime = startTime,
            endTime = endTime,
            startZoneOffset = ZoneOffset.UTC,
            endZoneOffset = ZoneOffset.UTC,
            metadata = Metadata.autoRecorded(
                device = Device(type = Device.TYPE_WATCH)
            )
        )
        healthConnectClient.insertRecords(listOf(stepsRecord))
    } catch (e: Exception) {
        // Run error handling here
    }
}

Обновить данные

Если вам необходимо изменить одну или несколько записей, особенно если требуется синхронизировать хранилище данных вашего приложения с данными из Health Connect, вы можете обновить свои данные. Существует два способа обновления существующих данных, которые зависят от идентификатора, используемого для поиска записей.

Метаданные

В первую очередь стоит изучить класс Metadata , поскольку он необходим при обновлении данных. При создании каждая Record в Health Connect имеет поле metadata . Для синхронизации важны следующие свойства:

Характеристики Описание
id Каждая Record в Health Connect имеет уникальное id значение.
Система Health Connect автоматически заполняет это поле при добавлении новой записи.
lastModifiedTime Каждая Record также отслеживает время последнего изменения записи.
Health Connect автоматически заполняет эту информацию.
clientRecordId Каждой Record может быть присвоен уникальный идентификатор, который будет служить ссылкой в ​​хранилище данных вашего приложения.
Ваше приложение предоставляет эту ценность.
clientRecordVersion Если запись имеет clientRecordId , то clientRecordVersion можно использовать для синхронизации данных с версией, хранящейся в хранилище данных вашего приложения.
Ваше приложение предоставляет эту ценность.

Обновление после прочтения по временному диапазону

Для обновления данных сначала подготовьте необходимые записи. При необходимости внесите изменения в записи. Затем вызовите updateRecords для внесения изменений.

В следующем примере показано, как обновить данные. Для этого значения смещения зоны для каждой записи корректируются в соответствии с PST-тематикой.

suspend fun updateSteps(
    healthConnectClient: HealthConnectClient,
    prevRecordStartTime: Instant,
    prevRecordEndTime: Instant
) {
    try {
        val request = healthConnectClient.readRecords(
            ReadRecordsRequest(
                recordType = StepsRecord::class, timeRangeFilter = TimeRangeFilter.between(
                    prevRecordStartTime, prevRecordEndTime
                )
            )
        )

        val newStepsRecords = arrayListOf<StepsRecord>()
        for (record in request.records) {
            // Adjusted both offset values to reflect changes
            val sr = StepsRecord(
                count = record.count,
                startTime = record.startTime,
                startZoneOffset = record.startTime.atZone(ZoneId.of("PST")).offset,
                endTime = record.endTime,
                endZoneOffset = record.endTime.atZone(ZoneId.of("PST")).offset,
                metadata = record.metadata
            )
            newStepsRecords.add(sr)
        }

        healthConnectClient.updateRecords(newStepsRecords)
    } catch (e: Exception) {
        // Run error handling here
    }
}

Вставка/обновление через идентификатор записи клиента

Если вы используете необязательные значения идентификатора записи клиента и версии записи клиента, мы рекомендуем использовать insertRecords вместо updateRecords .

Функция insertRecords позволяет обновлять или вставлять данные. Если данные существуют в Health Connect на основе заданного набора идентификаторов записей клиентов, они перезаписываются. В противном случае они записываются как новые данные. Этот сценарий полезен, когда необходимо синхронизировать данные из хранилища данных вашего приложения с Health Connect.

В следующем примере показано, как выполнить операцию обновления/вставки данных, полученных из хранилища данных приложения:

suspend fun pullStepsFromDatastore() : ArrayList<StepsRecord> {
    val appStepsRecords = arrayListOf<StepsRecord>()
    // Pull data from app datastore
    // ...
    // Make changes to data if necessary
    // ...
    // Store data in appStepsRecords
    // ...
    var sr = StepsRecord(
        metadata = Metadata.autoRecorded(
            clientRecordId = "Your client record ID",
            device = Device(type = Device.TYPE_WATCH)
        ),
        // Assign more parameters for this record
    )
    appStepsRecords.add(sr)
    // ...
    return appStepsRecords
}

suspend fun upsertSteps(
    healthConnectClient: HealthConnectClient,
    newStepsRecords: ArrayList<StepsRecord>
) {
    try {
        healthConnectClient.insertRecords(newStepsRecords)
    } catch (e: Exception) {
        // Run error handling here
    }
}

После этого вы можете вызывать эти функции в основном потоке.

upsertSteps(healthConnectClient, pullStepsFromDatastore())

Проверка значения в версии записи клиента

Если в процессе обновления/вставки данных используется параметр «Версия записи клиента», Health Connect выполняет проверку сравнения значений clientRecordVersion . Если версия вставляемых данных выше версии существующих данных, обновление/вставка происходит. В противном случае процесс игнорирует изменение, и значение остается прежним.

Для включения версионирования в ваши данные необходимо передать в Metadata.clientRecordVersion значение типа Long , соответствующее вашей логике версионирования.

val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofMinutes(15))

val stepsRecord = StepsRecord(
    count = 100L,
    startTime = startTime,
    startZoneOffset = ZoneOffset.UTC,
    endTime = endTime,
    endZoneOffset = ZoneOffset.UTC,
    metadata = Metadata.manualEntry(
        clientRecordId = "Your supplied record ID",
        clientRecordVersion = 0L, // Your supplied record version
        device = Device(type = Device.TYPE_WATCH)
    )
)

При обновлении/вставке (upsert) version не увеличивается автоматически при каждом изменении, что предотвращает непредвиденные случаи перезаписи данных. В этом случае вам придется вручную указывать более высокое значение.

Общие рекомендации

Ваше приложение должно записывать все поддерживаемые собственные данные. При желании вы можете настроить приложение на запись данных, полученных из сторонних источников. Однако, если ваше приложение считывало данные из Health Connect, эти данные не должны записываться обратно в Health Connect.

При записи данных, импортированных или полученных из другого источника, необходимо корректно указать источник и метаданные исходного устройства. Для этого для каждой записи необходимо предоставить следующие метаданные:

  • recordingMethod : Для данных, записанных автоматически или вручную, мы ожидаем, что метод записи будет обновлен в соответствии с типом записанной активности:
    • RECORDING_METHOD_AUTOMATICALLY_RECORDED : Если данные записывались автоматически, например, фитнес-браслет автоматически определял, что пользователь отправился на пробежку.
    • RECORDING_METHOD_ACTIVELY_RECORDED : Если пользователь начал новую активность, например, езду на велосипеде с помощью своего носимого устройства.
    • RECORDING_METHOD_MANUAL_ENTRY : Если пользователь ввел данные вручную.
  • device.type : Необходимо указать тип устройства из числа поддерживаемых типов Device .
  • device.manufacturer : Производитель устройства, например, "Fitbit".
  • device.model : Модель устройства, например, "Charge 3".

Правильная настройка метаданных имеет решающее значение для прозрачности данных и помогает пользователям понимать, откуда поступает информация об их здоровье. Для получения полной информации обратитесь к руководству по метаданным Health Connect.

Если данные в вашем приложении были импортированы из другого приложения, то ответственность за запись собственных данных в Health Connect ложится на это другое приложение.

Также целесообразно реализовать логику обработки исключений при записи, таких как выход данных за пределы допустимого диапазона или внутренняя системная ошибка. Стратегии отсрочки и повторных попыток можно применить к механизму планирования заданий. Если запись в Health Connect в конечном итоге окажется неудачной, убедитесь, что ваше приложение может продолжить работу после этого этапа экспорта. Не забудьте регистрировать и сообщать об ошибках для облегчения диагностики.

При отслеживании данных можно следовать нескольким рекомендациям в зависимости от способа записи данных вашим приложением.

Обработка часовых поясов

При записи записей, привязанных ко времени, избегайте установки смещения в zoneOffset.UTC по умолчанию, поскольку это может привести к неточным меткам времени, когда пользователи находятся в других часовых поясах. Вместо этого вычисляйте смещение на основе фактического местоположения устройства. Вы можете получить часовой пояс устройства, используя ZoneId.systemDefault() .

val endTime = Instant.now()
val startTime = endTime.minus(java.time.Duration.ofDays(1))
val stepsRecords = mutableListOf<StepsRecord>()
var sampleTime = startTime
val minutesBetweenSamples = 15L
while (sampleTime < endTime) {
    // Get the default ZoneId then convert it to an offset
    val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(sampleTime)
    stepsRecords += StepsRecord(
        startTime = sampleTime.minus(java.time.Duration.ofMinutes(minutesBetweenSamples)),
        startZoneOffset = zoneOffset,
        endTime = sampleTime,
        endZoneOffset = zoneOffset,
        count = Random.nextLong(1, 100),
        metadata = Metadata.unknownRecordingMethod(),
    )
    sampleTime = sampleTime.plus(java.time.Duration.ofMinutes(minutesBetweenSamples))
}
healthConnectClient.insertRecords(
    stepsRecords
)

Для получения более подробной информации см. документацию по ZoneId .

Укажите частоту и детализацию.

При записи данных в Health Connect используйте соответствующее разрешение. Использование правильного разрешения помогает снизить нагрузку на хранилище, сохраняя при этом согласованность и точность данных. Разрешение данных включает в себя два аспекта:

  • Частота записи : Как часто ваше приложение записывает новые данные в Health Connect.
    • По мере поступления новых данных записывайте их как можно чаще, при этом учитывая производительность устройства.
    • Во избежание негативного влияния на время автономной работы и другие параметры производительности, максимальный интервал между операциями записи должен составлять 15 минут.
  • Детализация письменных данных : как часто проводилась выборка данных.
    • Например, записывайте данные о частоте сердечных сокращений каждые 5 секунд.
    • Не для всех типов данных требуется одинаковая частота дискретизации. Обновление данных о количестве шагов каждую секунду имеет мало преимуществ по сравнению с менее частым интервалом, например, каждые 60 секунд.
    • Более высокая частота дискретизации может предоставить пользователям более детальный и подробный анализ данных об их здоровье и физической форме. Частота дискретизации должна обеспечивать баланс между детализацией и производительностью.

Дополнительные рекомендации

При записи данных следуйте этим рекомендациям:

  • При каждой синхронизации записывайте только новые данные и обновленные данные, которые были изменены с момента последней синхронизации.
  • За один запрос на запись обрабатывайте не более 1000 записей.
  • Ограничьте выполнение задач только тогда, когда устройство находится в режиме ожидания и уровень заряда батареи достаточно высок.
  • Для фоновых задач используйте WorkManager для планирования периодических задач с максимальным интервалом времени в 15 минут.

Приведенный ниже код использует WorkManager для планирования периодических фоновых задач с максимальным периодом времени 15 минут и гибким интервалом в 5 минут. Эта конфигурация задается с помощью класса PeriodicWorkRequest.Builder .

val constraints = Constraints.Builder()
    .requiresBatteryNotLow()
    .requiresDeviceIdle(true)
    .build()

val writeDataWork = PeriodicWorkRequestBuilder<WriteDataToHealthConnectWorker>(
        15,
        TimeUnit.MINUTES,
        5,
        TimeUnit.MINUTES
    )
    .setConstraints(constraints)
    .build()

Активное отслеживание

Сюда входят приложения, которые отслеживают события, такие как физические упражнения и сон, или вводят данные вручную, например, о питании. Эти записи создаются, когда приложение находится на переднем плане, или в редких случаях, когда оно используется несколько раз в день.

Убедитесь, что ваше приложение не поддерживает работу Health Connect на протяжении всего мероприятия.

Данные в Health Connect необходимо записывать одним из двух способов:

  • Синхронизируйте данные с Health Connect после завершения события. Например, синхронизируйте данные, когда пользователь завершает отслеживаемую тренировку.
  • Запланируйте разовую задачу с помощью WorkManager для последующей синхронизации данных.

Рекомендации по обеспечению детализации и частоты операций записи.

При записи данных в Health Connect используйте соответствующее разрешение. Использование подходящего разрешения помогает снизить нагрузку на хранилище, сохраняя при этом согласованность и точность данных. Разрешение данных включает в себя два аспекта:

  1. Частота записи : как часто ваше приложение отправляет новые данные в Health Connect. Записывайте данные как можно чаще, когда они становятся доступны, но при этом учитывайте производительность устройства. Чтобы избежать негативного влияния на время работы батареи и другие аспекты производительности, максимальный интервал между записями должен составлять 15 минут.

  2. Детализация записываемых данных : как часто регистрировались передаваемые данные. Например, частота сердечных сокращений регистрируется каждые 5 секунд. Не для всех типов данных требуется одинаковая частота дискретизации. Обновление данных о количестве шагов каждую секунду не приносит большой пользы по сравнению с менее частым интервалом, например, каждые 60 секунд. Однако более высокая частота дискретизации может предоставить пользователям более детальный и подробный анализ данных о здоровье и физической активности. Частота дискретизации должна обеспечивать баланс между детализацией и производительностью.

Структурные записи для данных серий

Для типов данных, использующих серию выборок, таких как HeartRateRecord , важно правильно структурировать записи. Вместо создания одной записи на весь день, которая постоянно обновляется, следует создать несколько более мелких записей, каждая из которых представляет определенный временной интервал.

Например, для данных о частоте сердечных сокращений следует создавать новую HeartRateRecord для каждой минуты. Каждая запись будет содержать время начала и окончания в течение этой минуты и будет включать все значения частоты сердечных сокращений, зафиксированные за эту минуту.

В процессе регулярной синхронизации с Health Connect (например, каждые 15 минут) ваше приложение должно записывать все записи, созданные за одну минуту с момента предыдущей синхронизации. Это позволяет поддерживать размер записей в приемлемом диапазоне и повышает производительность запросов и обработки данных.

В следующем примере показано, как создать запись HeartRateRecord за одну минуту, содержащую несколько выборок:

val startTime = Instant.now().truncatedTo(ChronoUnit.MINUTES)
val endTime = startTime.plus(Duration.ofMinutes(1))

val heartRateRecord = HeartRateRecord(
    startTime = startTime,
    startZoneOffset = ZoneOffset.UTC,
    endTime = endTime,
    endZoneOffset = ZoneOffset.UTC,
    // Create a new record every minute, containing a list of samples.
    samples = listOf(
        HeartRateRecord.Sample(
            time = startTime + Duration.ofSeconds(15),
            beatsPerMinute = 80,
        ),
        HeartRateRecord.Sample(
            time = startTime + Duration.ofSeconds(30),
            beatsPerMinute = 82,
        ),
        HeartRateRecord.Sample(
            time = startTime + Duration.ofSeconds(45),
            beatsPerMinute = 85,
        )
    ),
    metadata = Metadata.autoRecorded(
        device = Device(type = Device.TYPE_WATCH)
    ))

Запись данных, отслеживаемых в течение дня.

Для данных, собираемых на постоянной основе, например, количества шагов, ваше приложение должно как можно чаще записывать данные в Health Connect при их поступлении. Чтобы избежать негативного влияния на время работы батареи и другие параметры производительности, максимальный интервал между записями должен составлять 15 минут.

Таблица 1: Рекомендации по записи данных

Тип данных

Единица

Ожидал

Пример

Шаги

шаги

Каждую 1 минуту

23:14 - 23:15 - 5 шагов

23:16 - 23:17 - 22 шага

23:17 - 23:18 - 8 шагов

ШагиКаденция

шагов/мин

Каждую 1 минуту

23:14 - 23:15 - 5 часов в минуту

23:16 - 23:17 - 22 spm

23:17 - 23:18 - 8 часов в минуту

Толкание инвалидной коляски

толкает

Каждую 1 минуту

23:14 - 23:15 - 5 толканий

23:16 - 23:17 - 22 толчка

23:17 - 23:18 - 8 толканий

Активные сожженные калории

Калории

Каждые 15 минут

23:15 - 23:30 - 2 калории

23:30 - 23:45 - 25 калорий

23:45 - 00:00 - 5 калорий

Общее количество сожженных калорий

Калории

Каждые 15 минут

23:15 - 23:30 - 16 калорий

23:30 - 23:45 - 16 калорий

23:45 - 00:00 - 16 калорий

Расстояние

км/мин

Каждую 1 минуту

23:14-23:15 - 0,008 км

23:16 - 23:16 - 0,021 км

23:17 - 23:18 - 0,012 км

ElevationGained

м

Каждую 1 минуту

20:36 - 20:37 - 3.048м

20:39 - 20:40 - 3.048м

23:23 - 23:24 - 9.144м

Поднявшиеся этажи

полы

Каждую 1 минуту

23:14 - 23:15 - 5 этажей

23:16 - 23:16 - 22 этажа

23:17 - 23:18 - 8 этажей

Частота сердечных сокращений

ударов в минуту

4 раза в минуту

6:11:15 утра - 55 ударов в минуту

6:11:30 утра - 56 ударов в минуту

6:11:45 утра - 56 ударов в минуту

6:12:00 утра - 55 ударов в минуту

Вариабельность сердечного ритмаRmssd

РС

Каждую 1 минуту

6:11 утра - 23 мс

Частота дыхания

вдохов/минуту

Каждую 1 минуту

23:14 - 23:15 - 60 вдохов/минуту

23:16 - 23:16 - 62 вдоха/минуту

23:17 - 23:18 - 64 вдоха/минуту

Насыщение кислородом

%

Каждый час

6:11 - 95,208%

Данные в Health Connect следует записывать в конце тренировки или сна. Для активного отслеживания, например, физических упражнений и сна, или ручного ввода пользователем данных, таких как питание, эти записи создаются, когда приложение находится в фоновом режиме, или в редких случаях, когда оно используется несколько раз в день.

Убедитесь, что ваше приложение не поддерживает работу Health Connect на протяжении всего мероприятия.

Данные в Health Connect необходимо записывать одним из двух способов:

  • Синхронизируйте данные с Health Connect после завершения события. Например, синхронизируйте данные, когда пользователь завершает отслеживаемую тренировку.
  • Запланируйте разовую задачу с помощью WorkManager для последующей синхронизации данных.

Занятия спортом и сон

Как минимум, ваше приложение должно соответствовать рекомендациям в столбце «Ожидаемые результаты » в таблице 2. По возможности, следуйте рекомендациям в столбце «Наилучшие результаты ».

В следующей таблице показано, как записывать данные во время выполнения упражнения:

Таблица 2: Рекомендации по записи данных во время тренировки.

Тип данных

Единица

Ожидал

Лучший

Пример

Шаги

шаги

Каждую 1 минуту

Каждую секунду

23:14-23:15 - 5 шагов

23:16 - 23:17 - 22 шага

23:17 - 23:18 - 8 шагов

ШагиКаденция

шагов/мин

Каждую 1 минуту

Каждую секунду

23:14-23:15 - 35 спм

23:16 - 23:17 - 37 spm

23:17 - 23:18 - 40 спм

Толкание инвалидной коляски

толкает

Каждую 1 минуту

Каждую секунду

23:14-23:15 - 5 потуг

23:16 - 23:17 - 22 толчка

23:17 - 23:18 - 8 толканий

ВелоспортКрутящий моментЧастота вращения педалей

об/мин

Каждую 1 минуту

Каждую секунду

23:14-23:15 - 65 об/мин

23:16 - 23:17 - 70 об/мин

23:17 - 23:18 - 68 об/мин

Власть

ватты

Каждую 1 минуту

Каждую секунду

23:14-23:15 - 250 ватт

23:16 - 23:17 - 255 ватт

23:17 - 23:18 - 245 ватт

Скорость

км/мин

Каждую 1 минуту

Каждую секунду

23:14-23:15 - 0,3 км/мин

23:16 - 23:17 - 0,4 км/мин

23:17 - 23:18 -0,4 км/мин

Расстояние

км/м

Каждую 1 минуту

Каждую секунду

23:14-23:15 - 0,008 км

23:16 - 23:16 - 0,021 км

23:17 - 23:18 - 0,012 км

Активные сожженные калории

Калории

Каждую 1 минуту

Каждую секунду

23:14-23:15 - 20 калорий

23:16 - 23:17 - 20 калорий

23:17 - 23:18 - 25 калорий

Общее количество сожженных калорий

Калории

Каждую 1 минуту

Каждую секунду

23:14-23:15 - 36 калорий

23:16 - 23:17 - 36 калорий

23:17 - 23:18 - 41 калория

ElevationGained

м

Каждую 1 минуту

Каждую секунду

20:36 - 20:37 - 3.048м

20:39 - 20:40 - 3.048м

23:23 - 23:24 - 9.144м

Маршруты упражнений

широта/долгота/высота

Каждые 3-5 секунд

Каждую секунду

Частота сердечных сокращений

ударов в минуту

4 раза в минуту

Каждую секунду

23:14-23:15 - 150 ударов в минуту

В таблице 3 показано, как записывать данные во время или после сеанса сна:

Таблица 3: Рекомендации по записи данных во время или после сеанса сна.

Тип данных

Единица

Ожидаемые образцы

Пример

Стадии сна

этап

Детальный временной промежуток для каждой стадии сна

23:46 - 23:50 - бодрствование

23:50 - 23:56 - лёгкий сон

23:56 - 00:16 - глубокий сон

Частота сердечных сокращений в состоянии покоя

ударов в минуту

Однократное значение за сутки (ожидается утром сразу после пробуждения)

6:11 утра - 60 ударов в минуту

Насыщение кислородом

%

Однократное значение за сутки (ожидается утром сразу после пробуждения)

6:11 - 95,208%

Многопрофильные спортивные мероприятия

Этот подход использует существующие типы и структуры данных и проверяет совместимость с текущими реализациями Health Connect и средствами чтения данных. Это распространенный подход, используемый фитнес-платформами.

Кроме того, отдельные тренировки, такие как плавание, езда на велосипеде и бег, не связаны между собой напрямую в Health Connect, и пользователям приходится выводить взаимосвязь между этими тренировками, исходя из их временной близости. Переходы между сегментами, например, от плавания к езде на велосипеде, явно не отображаются.

В следующем примере показано, как записывать данные для триатлона:

val swimStartTime = Instant.parse("2024-08-22T08:00:00Z")
val swimEndTime = Instant.parse("2024-08-22T08:30:00Z")
val bikeStartTime = Instant.parse("2024-08-22T08:40:00Z")
val bikeEndTime = Instant.parse("2024-08-22T09:40:00Z")
val runStartTime = Instant.parse("2024-08-22T09:50:00Z")
val runEndTime = Instant.parse("2024-08-22T10:20:00Z")

val swimSession = ExerciseSessionRecord(
    startTime = swimStartTime,
    endTime = swimEndTime,
    exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_OPEN_WATER,
    metadata = Metadata.autoRecorded(
      device = Device(type = Device.TYPE_WATCH)
    )
)

val bikeSession = ExerciseSessionRecord(
    startTime = bikeStartTime,
    endTime = bikeEndTime,
    exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_BIKING,
    metadata = Metadata.autoRecorded(
      device = Device(type = Device.TYPE_WATCH)
    )
)

val runSession = ExerciseSessionRecord(
    startTime = runStartTime,
    endTime = runEndTime,
    exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
    metadata = Metadata.autoRecorded(
      device = Device(type = Device.TYPE_WATCH)
    )
)

healthConnectClient.insertRecords(listOf(swimSession, bikeSession, runSession))

Обработка исключений

В случае возникновения проблем Health Connect генерирует стандартные исключения для операций CRUD. Ваше приложение должно перехватывать и обрабатывать каждое из этих исключений соответствующим образом.

В каждом методе класса HealthConnectClient перечислены исключения, которые могут быть сгенерированы. В целом, ваше приложение должно обрабатывать следующие исключения:

Таблица 1: Исключения в программе Health Connect и рекомендуемые передовые методы.
Исключение Описание Рекомендуемые лучшие практики
IllegalStateException Произошло одно из следующих событий:

  • Сервис Health Connect недоступен.
  • Данный запрос не является допустимой конструкцией. Например, агрегированный запрос в периодических интервалах, где для параметра timeRangeFilter используется объект Instant .

Перед отправкой запроса сначала обработайте возможные проблемы с входными данными. Желательно присваивать значения переменным или использовать их в качестве параметров в пользовательской функции, а не использовать их напрямую в запросах, чтобы иметь возможность применять стратегии обработки ошибок.
IOException При чтении и записи данных с диска возникают проблемы. Чтобы избежать этой проблемы, предлагаем следующие варианты:

  • Создайте резервную копию всего пользовательского ввода.
  • Умейте справляться с любыми проблемами, возникающими во время операций массовой записи. Например, убедитесь, что процесс преодолевает проблему и выполняет оставшиеся операции.
  • Для обработки проблем с запросами используйте стратегии повторных попыток и задержки.

RemoteException Ошибки возникли внутри или при взаимодействии с базовой службой, к которой подключается SDK.

Например, ваше приложение пытается удалить запись с заданным uid . Однако исключение возникает после того, как приложение, проверив данные в базовом сервисе, обнаруживает, что запись не существует.
Чтобы избежать этой проблемы, предлагаем следующие варианты:

  • Регулярно синхронизируйте хранилище данных вашего приложения с Health Connect.
  • Для обработки проблем с запросами используйте стратегии повторных попыток и задержки.

SecurityException Проблемы возникают, когда запросы требуют разрешений, которые не предоставлены. Чтобы этого избежать, убедитесь, что вы указали использование типов данных Health Connect для опубликованного приложения. Кроме того, необходимо указать разрешения Health Connect в файле манифеста и в вашем Activity .