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

Это руководство совместимо с Health Connect версии 1.1.0-alpha12 .

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

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

Прежде чем записывать данные, нам необходимо сначала настроить записи. Для более чем 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 может хранить значения вместе с единицами измерения для обеспечения точности. Одним из примеров является обширный и всеобъемлющий тип данных «Питание» . Он включает в себя широкий спектр дополнительных питательных веществ, от общего количества углеводов до витаминов. Каждая точка данных представляет питательные вещества, которые потенциально были употреблены как часть еды или продукта питания.

В этом типе данных все питательные вещества представлены в единицах Mass , а energy — в единицах 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 параметров представлены списком образцов частоты пульса . Каждая выборка содержит 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)
    ))

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

Одним из распространенных рабочих процессов в 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)
    )
)

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%

,

Это руководство совместимо с Health Connect версии 1.1.0-alpha12 .

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

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

Прежде чем записывать данные, нам необходимо сначала настроить записи. Для более чем 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 может хранить значения вместе с единицами измерения для обеспечения точности. Одним из примеров является обширный и всеобъемлющий тип данных «Питание» . Он включает в себя широкий спектр дополнительных питательных веществ, от общего количества углеводов до витаминов. Каждая точка данных представляет питательные вещества, которые потенциально были употреблены как часть еды или продукта питания.

В этом типе данных все питательные вещества представлены в единицах Mass , а energy — в единицах 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 параметров представлены списком образцов частоты пульса . Каждая выборка содержит 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)
    ))

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

Одним из распространенных рабочих процессов в 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)
    )
)

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%

,

Это руководство совместимо с Health Connect версии 1.1.0-alpha12 .

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

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

Прежде чем записывать данные, нам необходимо сначала настроить записи. Для более чем 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 может хранить значения вместе с единицами измерения для обеспечения точности. Одним из примеров является обширный и всеобъемлющий тип данных «Питание» . Он включает в себя широкий спектр дополнительных питательных веществ, от общего количества углеводов до витаминов. Каждая точка данных представляет питательные вещества, которые потенциально были употреблены как часть еды или продукта питания.

В этом типе данных все питательные вещества представлены в единицах Mass , а energy — в единицах 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 параметров представлены списком образцов частоты пульса . Каждая выборка содержит 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)
    ))

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

Одним из распространенных рабочих процессов в 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)
    )
)

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 SPM

23:16 - 23:17 - 37 SPM

23:17 - 23:18 - 40 SPM

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

Толкает

Каждую 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 км

ActiveCalories Burn

Калории

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

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

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

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

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

TotalCalories Burn

Калории

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

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

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

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

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

Eailtiongared

м

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

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

20:36 - 20:37 - 3.048M

20:39 - 20:40 - 3.048M

23:23 - 23:24 - 9.144M

Упражнение

LAT/LNG/ALT

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

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

Уровень

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

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

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

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

23:16 - 23:17 -152 BPM

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

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

Тип данных

Единица

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

Пример

Постановка сна

этап

Гранулированный период времени на стадию сна

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

23:50 - 23:56 - Легкий сон

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

RestingHeartTrate

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

Одиночная ежедневная стоимость (ожидаемая первая вещь по утрам)

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

Оксигенсатурация

%

Одиночная ежедневная стоимость (ожидаемая первая вещь по утрам)

6:11 - 95,208%

,

Это руководство совместимо с Health Connect Version 1.1.0-Alpha12 .

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

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

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

В этом типе данных все питательные вещества представлены в единицах Mass , а energy представлена ​​в единице 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 параметров представлены списком образцов сердечного ритма . Каждый образец содержит значения 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)
    ))

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

Одним из распространенных рабочих процессов в 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
    }
}

Upsert через идентификатор записи клиента

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

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

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

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())

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

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

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

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

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

Лучшие практики для написания данных

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

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

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

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

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

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

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

  • На каждом синхронизации записывают только новые данные и обновленные данные, которые были изменены с момента последней синхронизации.
  • Запросы Chunk не менее 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 используйте соответствующее разрешение. Использование соответствующего разрешения помогает уменьшить нагрузку на хранение, при этом сохраняя постоянные и точные данные. Разрешение данных охватывает 2 вещи:

  1. Частота записей : как часто ваше приложение выдвигает любые новые данные в 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 SPM

23:16 - 23:17 - 22 SPM

23:17 - 23:18 - 8 SPM

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

Толкает

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

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

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

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

ActiveCalories Burn

Калории

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

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

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

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

TotalCalories Burn

Калории

Каждые 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 км

Eailtiongared

м

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

20:36 - 20:37 - 3.048M

20:39 - 20:40 - 3.048M

23:23 - 23:24 - 9.144M

Полы

полы

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

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

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

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

Уровень

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

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

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

Earttratevarabilityrmssd

РС

Каждую 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 SPM

23:16 - 23:17 - 37 SPM

23:17 - 23:18 - 40 SPM

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

Толкает

Каждую 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 км

ActiveCalories Burn

Калории

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

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

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

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

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

TotalCalories Burn

Калории

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

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

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

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

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

Eailtiongared

м

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

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

20:36 - 20:37 - 3.048M

20:39 - 20:40 - 3.048M

23:23 - 23:24 - 9.144M

Упражнение

LAT/LNG/ALT

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

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

Уровень

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

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

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

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

23:16 - 23:17 -152 BPM

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

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

Тип данных

Единица

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

Пример

Постановка сна

этап

Гранулированный период времени на стадию сна

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

23:50 - 23:56 - Легкий сон

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

RestingHeartTrate

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

Одиночная ежедневная стоимость (ожидаемая первая вещь по утрам)

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

Оксигенсатурация

%

Одиночная ежедневная стоимость (ожидаемая первая вещь по утрам)

6:11 - 95,208%