Требования к метаданным

Это руководство совместимо с версией 1.2.0-alpha05 и более поздними версиями платформы "Здоровье и спорт".

В метаданных платформы "Здоровье и спорт" произошли изменения, которые касаются разработчиков, перешедших на версию 1.1.0-alpha12 или более позднюю.

Информация о библиотеке

Идентификатор артефакта плагина Android Gradle для Google Maven определяет библиотеку "Здоровье и спорт", которую нужно обновить. Добавьте зависимость Health Connect SDK в файл build.gradle на уровне модуля:

dependencies {
  implementation "androidx.health.connect:connect-client:1.1.0-alpha12"
}

Изменения метаданных

В Health Connect Jetpack SDK версии 1.1.0-alpha12 добавлены два изменения метаданных, которые помогают проверять наличие в экосистеме дополнительной полезной информации. Если в конструкторе Record не указан параметр metadata, может появиться ошибка Constructor internal.

Как указать способ записи

При создании объекта типа Record() необходимо указать сведения о метаданных.

При записи данных в Здоровье и спорт необходимо указать один из четырех методов записи, используя один из соответствующих фабричных методов для создания экземпляра Metadata:

Способ записи Описание
RECORDING_METHOD_UNKNOWN Не удалось проверить способ записи.
RECORDING_METHOD_MANUAL_ENTRY Пользователь ввел данные.
RECORDING_METHOD_AUTOMATICALLY_RECORDED Данные были записаны устройством или датчиком.
RECORDING_METHOD_ACTIVELY_RECORDED Пользователь запустил или завершил сеанс записи на устройстве.

Пример:

 StepsRecord(
    startTime = Instant.ofEpochMilli(1234L),
    startZoneOffset = null,
    endTime = Instant.ofEpochMilli(1236L),
    endZoneOffset = null,
    metadata = Metadata.activelyRecorded(device = Device(type = Device.TYPE_WATCH)),
    count = 10
)

Тип устройства

Для всех автоматически и активно записанных данных необходимо указать тип устройства. Подробнее о классе Device в документации Jetpack… В настоящее время поддерживаются следующие типы устройств:

Тип устройства Описание
TYPE_UNKNOWN Тип устройства неизвестен.
TYPE_WATCH Тип устройства – часы.
TYPE_PHONE Тип устройства – телефон.
TYPE_SCALE Тип устройства – весы.
TYPE_RING Тип устройства – кольцо.
TYPE_HEAD_MOUNTED Тип устройства – носимое на голове устройство.
TYPE_FITNESS_BAND Тип устройства – фитнес-трекер.
TYPE_CHEST_STRAP Тип устройства – нагрудный ремень.
TYPE_SMART_DISPLAY Тип устройства – умный дисплей.

Некоторые значения Device.type доступны только в более поздних версиях Health Connect. Если функция расширенных типов устройств недоступна, эти типы будут рассматриваться как Device.TYPE_UNKNOWN.

Расширенные типы устройств Описание
TYPE_CONSUMER_MEDICAL_DEVICE Тип устройства – медицинское устройство.
TYPE_GLASSES Тип устройства – умные очки.
TYPE_HEARABLE Тип устройства – слуховой аппарат.
TYPE_FITNESS_MACHINE Тип устройства – стационарный компьютер.
TYPE_FITNESS_EQUIPMENT Тип устройства – тренажер.
TYPE_PORTABLE_COMPUTER Тип устройства – портативный компьютер.
TYPE_METER Тип устройства – измерительный прибор.
Чтобы узнать, поддерживает ли устройство пользователя расширенные типы устройств в Health Connect, проверьте наличие значка FEATURE_EXTENDED_DEVICE_TYPES в клиенте:

if (healthConnectClient
     .features
     .getFeatureStatus(
       HealthConnectFeatures.FEATURE_EXTENDED_DEVICE_TYPES
     ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE) {

  // Feature is available
} else {
  // Feature isn't available
}
Подробнее о том, как проверить доступность функции…

Пример:

 val WATCH_DEVICE = Device(
    manufacturer = "Google",
    model = "Pixel Watch",
    type = Device.TYPE_WATCH
)

// Phone
 val PHONE_DEVICE = Device(
    manufacturer = "Google",
    model = "Pixel 8",
    type = Device.TYPE_PHONE
)

// Ring
 val RING_DEVICE = Device(
    manufacturer = "Oura",
    model = "Ring Gen3",
    type = Device.TYPE_RING
)

// Scale
 val SCALE_DEVICE = Device(
    manufacturer = "Withings",
    model = "Body Comp",
    type = Device.TYPE_SCALE
)

Уникальный идентификатор устройства (UDI)

В приложении «Здоровье и спорт» для Android 17 (уровень API 37.1) или расширения U 23 или более поздней версии класс Device поддерживает уникальный идентификатор устройства (UDI). Если вы свяжете зарегистрированный UDI модели медицинского устройства с записями, то сможете передавать в другие приложения (например, на платформы телемедицины или клинические порталы) данные, полученные с медицинских устройств, и отличать их от данных, собранных обычными носимыми устройствами.

Объявите разрешение

Чтобы записывать UDI в сервис "Здоровье и спорт", необходимо объявить разрешение WRITE_DEVICE_UDI в файле AndroidManifest.xml приложения:

<uses-permission android:name="android.permission.health.WRITE_DEVICE_UDI" />

Обратите внимание, что WRITE_DEVICE_UDI – это обычное разрешение. Его нужно объявить в манифесте, но не нужно запрашивать у пользователя во время выполнения. Оно автоматически предоставляется приложению во время установки.

Запишите только идентификатор устройства (DI)

Полный UDI состоит из двух частей:

  • Идентификатор устройства (UDI-DI). Идентификатор, который присваивается определенной модели устройства агентством по выдаче (например, GS1) и признается во всем мире.
  • Идентификатор производства (UDI-PI) – атрибуты, относящиеся к определенному устройству, например серийный номер, номер партии, дата производства или срок годности.

Чтобы защитить конфиденциальность пользователя, в приложении "Здоровье и спорт" указывайте только часть кода UDI-DI. Не добавляйте атрибуты идентификаторов производства (например, серийные номера или номера партий).

Пример кода

Примечание. Уникальный идентификатор устройства можно задать при создании экземпляра Device.

Jetpack SDK

val device = Device(
    type = Device.TYPE_CONSUMER_MEDICAL_DEVICE,
    manufacturer = "Omron",
    model = "HEM-7121",
    udi = "04015674011832" // Device Identifier (UDI-DI) portion only
)

Platform API

val device = Device.Builder()
    .setType(Device.DEVICE_TYPE_CONSUMER_MEDICAL_DEVICE)
    .setManufacturer("Omron")
    .setModel("HEM-7121")
    .setUdi("04015674011832") // Device Identifier (UDI-DI) portion only
    .build()

Если вы записываете данные с UDI, не объявив разрешение WRITE_DEVICE_UDI, Здоровье и спорт выдает ошибку SecurityException во время записи.

Как использовать UDI для проверки очистки устройства

Платформа "Здоровье и спорт" выступает в качестве транспортного уровня и не проверяет подлинность или статус регистрации UDI.

Для считывателей данных наличие UDI означает, что данные получены от зарегистрированного медицинского устройства. Приложения для чтения должны запрашивать информацию из нормативных баз данных, таких как глобальная база данных уникальных идентификаторов устройств (GUDID) FDA или европейская база данных медицинских изделий (EUDAMED), чтобы проверять классификацию устройств, статус нормативного разрешения (например, класс I, II или III) или конкретное предполагаемое использование.

Фрагменты обновлены.

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

Новые методы работы с метаданными

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

  • activelyRecorded

    • fun activelyRecorded(device: Device): Metadata.
    • fun activelyRecorded(clientRecordId: String, clientRecordVersion: Long = 0, device: Device): Metadata
    • fun activelyRecordedWithId(id: String, device: Device): Metadata
  • autoRecorded

    • fun autoRecorded(device: Device): Metadata
    • fun autoRecorded(clientRecordId: String, clientRecordVersion: Long = 0, device: Device): Metadata
    • fun autoRecordedWithId(id: String, device: Device): Metadata
  • manualEntry

    • fun manualEntry(device: Device? = null): Metadata
    • fun manualEntry(clientRecordId: String, clientRecordVersion: Long = 0, device: Device? = null): Metadata
    • fun manualEntryWithId(id: String, device: Device? = null): Metadata
  • unknownRecordingMethod

    • fun unknownRecordingMethod(device: Device? = null): Metadata
    • fun unknownRecordingMethod(clientRecordId: String, clientRecordVersion: Long = 0, device: Device? = null): Metadata
    • fun unknownRecordingMethodWithId(id: String, device: Device? = null): Metadata

Дополнительную информацию можно найти на сайте Android Open Source Project.

Тестовые данные

Используйте Testing Library и MetadataTestHelper, чтобы имитировать ожидаемые значения метаданных:

private val TEST_METADATA =
    Metadata.unknownRecordingMethod(
        clientRecordId = "clientId",
        clientRecordVersion = 1L,
        device = Device(type = Device.TYPE_UNKNOWN),
    ).populatedWithTestValues(id = "test")

Это имитирует поведение реализации Здоровье и спорт, которая автоматически заполняет эти значения при вставке записи.

Чтобы использовать библиотеку тестирования, добавьте в файл build.gradle на уровне модуля следующую зависимость SDK Здоровья и спорта:

dependencies {
  testImplementation "androidx.health.connect:connect-testing:1.0.0-alpha02"
}

Как обновить библиотеку

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

  1. Обновите библиотеку до версии 1.1.0-alpha12.

  2. При создании библиотеки будут возникать ошибки компиляции, если потребуются новые метаданные. Чтобы устранить эти ошибки и завершить перенос, убедитесь, что вы внесли следующие изменения:

    • При создании Record обязательно нужно указать метод записи. Для этого используется один из фабричных методов, предоставленных в Metadata, например Metadata.manualEntry() или Metadata.activelyRecorded(device = Device(...)).
    • Для данных, записанных устройством, обязательно нужно указать тип устройства, например Device.TYPE_WATCH или Device.TYPE_PHONE.
  3. Если ваше приложение записывает расширенные типы устройств, используйте для них FEATURE_EXTENTED_DEVICE_TYPES, чтобы избежать неожиданных ошибок TYPE_UNKNOWN на устройствах, где эта функция недоступна.