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

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

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

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

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

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

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

val stepsRecord = StepsRecord(
    count = 120,
    startTime = START_TIME,
    endTime = END_TIME,
    startZoneOffset = START_ZONE_OFFSET,
    endZoneOffset = END_ZONE_OFFSET
)

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

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

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

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

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 = START_TIME,
    endTime = END_TIME,
    startZoneOffset = START_ZONE_OFFSET,
    endZoneOffset = END_ZONE_OFFSET
)

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

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

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

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

val heartRateRecord = HeartRateRecord(
    startTime = START_TIME,
    startZoneOffset = START_ZONE_OFFSET,
    endTime = END_TIME,
    endZoneOffset = END_ZONE_OFFSET,
    // records 10 arbitrary data, to replace with actual data
    samples = List(10) { index ->
        HeartRateRecord.Sample(
            time = START_TIME + Duration.ofSeconds(index.toLong()),
            beatsPerMinute = 100 + index.toLong(),
        )
    }
)

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

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

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

suspend fun insertSteps(healthConnectClient: HealthConnectClient) {
    try {
        val stepsRecord = StepsRecord(
            count = 120,
            startTime = START_TIME,
            endTime = END_TIME,
            startZoneOffset = START_ZONE_OFFSET,
            endZoneOffset = END_ZONE_OFFSET
        )
        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)
        }

        client.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(
        // Assign parameters for this record
        metadata = Metadata(
            clientRecordId = cid
        )
    )
    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 sr = StepsRecord(
    count = count,
    startTime = startTime,
    startZoneOffset = startZoneOffset,
    endTime = endTime,
    endZoneOffset = endZoneOffset,
    metadata = Metadata(
        clientRecordId = cid,
        clientRecordVersion = version
    )
)

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

Рекомендации по записи данных

Приложения должны записывать в Health Connect данные только из собственных источников .

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

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

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

Пассивное отслеживание

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

Вашему приложению необходимо периодически записывать данные в Health Connect следующими способами:

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

    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 секунд. Однако более высокая частота выборки может дать пользователям более подробный и детальный взгляд на данные об их здоровье и физической форме. Частоты дискретизации должны обеспечивать баланс между детализацией и производительностью.

Запись данных контролируется в течение дня

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

Тип данных

Единица

Ожидал

Пример

Шаги

шаги

Каждую 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 экз. в мин.

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 км

Высота получена

м

Каждую 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 этажей

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

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

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

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

Частота сердечных сокращенийВариабельностьRmssd

РС

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

6:11 – 23 мс

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

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

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

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

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

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

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

%

Каждый 1 час

6:11 - 95,208%

Написание сессий

Данные следует записывать в Health Connect в конце тренировки или сеанса сна.

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

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

Данные, отслеживаемые во время учений

Тип данных

Единица

Ожидал

Лучший

Пример

Шаги

шаги

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

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

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

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

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

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

шагов/мин

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

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

23:14-23:15 - 35 раз в минуту

23:16 - 23:17 - 37 экз. в мин.

23:17 - 23:18 - 40 выпусков в минуту

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

толкает

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

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

23:14-23:15 – 5 толчков

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

23:17 - 23:18 - 8 толчков

ВелоспортПедалиКаденция

об/мин

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

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

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

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

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

Власть

ватты

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

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

23:14-23:15 - 250 Вт

23:16 - 23:17 - 255 Вт

23:17 - 23:18 - 245 Вт

Скорость

км/мин

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

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

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

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

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

Расстояние

км/м

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

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

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

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

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

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

Калории

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

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

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

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

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

Всего калорий сожжено

Калории

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

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

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

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

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

Высота получена

м

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

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

20:36 - 20:37 - 3.048м

20:39 - 20:40 - 3.048м

23:23 - 23:24 - 9.144м

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

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

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

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

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

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

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

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

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

23:16 - 23:17 -152 ударов в минуту

23:17 - 23:18 - 155 ударов в минуту

Данные, отслеживаемые во время сна

Тип данных

Единица

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

Пример

Стадия сна

этап

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

23:46 - 23:50 - пробуждение

23:50 – 23:56 – легкий сон

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

ОтдыхСердцеЧастота

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

Единое дневное значение (ожидается утром)

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

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

%

Единое дневное значение (ожидается утром)

6:11 - 95,208%