Данное руководство совместимо с версией Health Connect 1.1.0-alpha12 .
Большинство приложений, интегрированных с Health Connect, имеют собственное хранилище данных, которое служит источником достоверной информации. Health Connect предоставляет способы синхронизации вашего приложения.
В зависимости от архитектуры вашего приложения, процесс синхронизации может включать в себя некоторые или все из следующих действий:
- Передавайте новые или обновленные данные из хранилища данных вашего приложения в Health Connect.
- Переносите изменения данных из Health Connect в хранилище данных вашего приложения.
- Удаляйте данные из Health Connect, когда они удаляются из хранилища данных вашего приложения.
В каждом случае убедитесь, что процесс синхронизации обеспечивает согласованность данных Health Connect и хранилища данных вашего приложения.
Передайте данные в Health Connect
Первый этап процесса синхронизации заключается в передаче данных из хранилища данных вашего приложения в хранилище данных Health Connect.
Подготовьте свои данные
Как правило, записи в хранилище данных вашего приложения содержат следующие сведения:
- Уникальный ключ, например,
UUID. - Версия или метка времени.
При синхронизации данных с Health Connect необходимо идентифицировать и передавать только те данные, которые были добавлены, обновлены или удалены с момента последней синхронизации.
Запись данных в Health Connect
Для передачи данных в Health Connect выполните следующие действия:
- Получите список новых, обновленных или удаленных записей из хранилища данных вашего приложения.
- Для каждой записи создайте объект
Record, соответствующий данному типу данных. Например, создайте объектWeightRecordдля данных, связанных с весом. Для каждой
Recordукажите объектMetadata. Он включаетclientRecordId— идентификатор из хранилища данных вашего приложения, который можно использовать для уникальной идентификации записи. Для этого можно использовать существующий уникальный ключ. Если ваши данные версионированы, укажите такжеclientRecordVersion, соответствующий используемой в данных системе версионирования. Если данные не версионированы, в качестве альтернативы можно использовать значениеLongтекущей метки времени.val recordVersion = 0L // Specify as needed // The clientRecordId is an ID that you choose for your record. This // is often the same ID you use in your app's datastore. val clientRecordId = "<your-record-id>" val record = WeightRecord( metadata = Metadata( clientRecordId = clientRecordId, clientRecordVersion = recordVersion, device = Device(type = Device.TYPE_SCALE) ), weight = Mass.kilograms(62.0), time = Instant.now(), zoneOffset = ZoneOffset.UTC, ) healthConnectClient.insertRecords(listOf(record))
Вставка данных в Health Connect с помощью
insertRecords. Вставка данных означает, что любые существующие данные в Health Connect перезаписываются, если значенияclientRecordIdсуществуют в хранилище данных Health Connect, аclientRecordVersionвыше существующего значения. В противном случае, вставляемые данные записываются как новые.healthConnectClient.insertRecords(arrayListOf(record))
Чтобы узнать о практических аспектах ввода данных, ознакомьтесь с рекомендациями по записи данных .
Сохранение идентификаторов Health Connect
Если ваше приложение также считывает данные из Health Connect, сохраняйте id Health Connect для записей после их обновления/вставки. Этот id необходим для обработки удалений при получении изменений данных из Health Connect.
Функция insertRecords возвращает объект InsertRecordsResponse , содержащий список значений id . Используйте этот ответ, чтобы получить идентификаторы записей и сохранить их.
val response = healthConnectClient.insertRecords(listOf(record)) for (recordId in response.recordIdsList) { // Store recordId to your app's datastore }
Получайте данные из Health Connect.
Вторая часть процесса синхронизации заключается в переносе всех изменений данных из Health Connect в хранилище данных вашего приложения. Изменения данных могут включать обновления и удаления.
Получите токен изменений
Чтобы получить список изменений для загрузки из Health Connect, вашему приложению необходимо отслеживать токены Changes . Вы можете использовать их при запросе Changes , чтобы получить как список изменений данных, так и новый токен Changes для использования в следующий раз.
Для получения токена изменений вызовите метод getChangesToken и укажите необходимые типы данных.
val changesToken = healthConnectClient.getChangesToken( ChangesTokenRequest(recordTypes = setOf(WeightRecord::class)) )
Проверьте наличие изменений данных.
Теперь, когда вы получили токен Changes , используйте его, чтобы получить все изменения . Мы рекомендуем создать цикл для перебора всех изменений , в котором будет проверяться наличие доступных изменений данных. Вот шаги:
- Вызовите
getChangesиспользуя токен, чтобы получить список изменений . - Проверьте каждое изменение, определите, является ли оно изменением типа
UpsertionChangeилиDeletionChange, и выполните необходимые операции.- При использовании
UpsertionChangeследует учитывать только те изменения, которые не были внесены вызывающим приложением, чтобы избежать повторного импорта данных.
- При использовании
- Присвойте следующему токену Changes ваш новый токен.
- Повторяйте шаги 1-3 до тех пор, пока не останется никаких изменений .
- Сохраните следующий токен и зарезервируйте его для будущего импорта.
suspend fun processChanges(context: Context, token: String): String { var nextChangesToken = token do { val response = healthConnectClient.getChanges(nextChangesToken) response.changes.forEach { change -> when (change) { is UpsertionChange -> if (change.record.metadata.dataOrigin.packageName != context.packageName) { processUpsertionChange(change) } is DeletionChange -> processDeletionChange(change) } } nextChangesToken = response.nextChangesToken } while (response.hasMore) // Return and store the changes token for use next time. return nextChangesToken }
Чтобы узнать о практических аспектах извлечения данных, ознакомьтесь с рекомендациями по синхронизации данных .
Изменения в технологических данных
Отразите изменения в хранилище данных вашего приложения. Для UpsertionChange используйте id и время lastModifiedTime из metadata для обновления или добавления записи. Для DeletionChange используйте предоставленный id для удаления записи. Для этого необходимо сохранить id записи, как указано в разделе «Хранение идентификаторов Health Connect» .
Удалить данные из Health Connect
Когда пользователь удаляет свои данные из вашего приложения, убедитесь, что эти данные также удалены из Health Connect. Для этого используйте deleteRecords . Эта функция принимает тип записи и список значений id и clientRecordId , что позволяет удобно объединять несколько записей для удаления. Также доступен альтернативный вариант deleteRecords , принимающий timeRangeFilter .
Синхронизация с низкой задержкой с помощью носимых устройств
Для синхронизации данных с носимого фитнес-устройства с Health Connect с низкой задержкой используйте CompanionDeviceService . Этот подход работает для устройств, поддерживающих уведомления или индикации BLE GATT и ориентированных на Android 8.0 (уровень API 26) или выше. CompanionDeviceService позволяет вашему приложению получать данные с носимых устройств и записывать их в Health Connect, даже если приложение еще не запущено. Для получения более подробной информации о лучших практиках BLE см. обзор Bluetooth Low Energy .
Подключите устройство
Во-первых, ваше приложение должно провести пользователя через одноразовую процедуру сопоставления носимого устройства с вашим приложением с помощью CompanionDeviceManager . Это предоставит вашему приложению необходимые разрешения для взаимодействия с устройством. Для получения дополнительной информации см. раздел «Сопряжение устройств Companion» .
Укажите услугу в манифесте.
Далее, объявите CompanionDeviceService в файле манифеста вашего приложения. Добавьте следующее в ваш файл AndroidManifest.xml :
<manifest ...>
<application ...>
<service
android:name=".MyWearableService"
android:exported="true"
android:permission="android.permission.BIND_COMPANION_DEVICE_SERVICE">
<intent-filter>
<action android:name="android.companion.CompanionDeviceService" />
</intent-filter>
</service>
</application>
</manifest>
Создать CompanionDeviceService
Наконец, создайте класс, расширяющий CompanionDeviceService . Этот сервис обрабатывает подключение к носимому устройству и получает данные через обратные вызовы BLE GATT. При получении новых данных они немедленно записываются в Health Connect.
private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) private var healthConnectClient: HealthConnectClient? = null private var bluetoothGatt: BluetoothGatt? = null override fun onDeviceAppeared(address: String) { super.onDeviceAppeared(address) healthConnectClient = HealthConnectClient.getOrCreate(this) serviceScope.launch { val granted = healthConnectClient?.permissionController?.getGrantedPermissions() // 1. Check permissions ONCE when the device connects if (granted?.contains(HealthPermission.getWritePermission(HeartRateRecord::class)) ?: false) { // This is where you'd actually start the Bluetooth connection // bluetoothGatt = gattCallback.connect(...) } // 2. Do your initial database read readExerciseSessionAndRoute() } } private val gattCallback = object : BluetoothGattCallback() { override fun onCharacteristicChanged( gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, value: ByteArray ) { super.onCharacteristicChanged(gatt, characteristic, value) // 3. ONLY process the incoming data here val rawData = value serviceScope.launch { // parseWearableData(rawData) // insertExerciseRoute() or writeToHealthConnect() } } }
Рекомендации по синхронизации данных
На процесс синхронизации влияют следующие факторы.
Срок действия токена истекает
Поскольку неиспользованный токен Changes истекает в течение 30 дней, необходимо использовать стратегию синхронизации, которая предотвратит потерю информации в таком случае. Ваша стратегия может включать следующие подходы:
- Найдите в хранилище данных вашего приложения последнюю использованную запись, которая также имеет
idиз Health Connect. - Запрашивайте у Health Connect записи, начинающиеся с определенной временной метки, а затем вставляйте или обновляйте их в хранилище данных вашего приложения.
- Запросите токен изменений, чтобы зарезервировать его для использования в следующий раз.
Рекомендуемые стратегии управления изменениями
В случае, если ваше приложение получает недействительные или просроченные токены изменений , мы рекомендуем следующие стратегии управления в зависимости от их применения в вашей логике:
- Прочитайте и удалите все дубликаты данных . Это наиболее оптимальная стратегия.
- Сохраните метку времени последнего считывания данных из Health Connect.
- По истечении срока действия токена повторно прочитайте все данные за последний период времени или за последние 30 дней. Затем проведите дедупликацию, используя идентификаторы, для сравнения с ранее прочитанными данными.
- В идеале следует внедрить идентификаторы клиентов, поскольку они необходимы для обновления данных.
- Читать следует только данные с момента последнего чтения . Это приводит к некоторым расхождениям в данных, связанных со временем истечения срока действия токена Changes, но этот период короче и может составлять от нескольких часов до нескольких дней.
- Сохраните метку времени последнего считывания данных из Health Connect.
- По истечении срока действия токена необходимо считать все данные, начиная с этой временной метки.
- Удалить, а затем прочитать данные за последние 30 дней . Это больше соответствует тому, что происходит при первой интеграции.
- Удалите все данные, считанные приложением из Health Connect за последние 30 дней.
- После удаления прочитайте все эти данные заново.
- Прочитывать данные за последние 30 дней без удаления дубликатов . Это наименее оптимальная стратегия, приводящая к отображению пользователям дублирующихся данных.
- Удалите все данные, считанные приложением из Health Connect за последние 30 дней.
- Разрешить повторяющиеся записи.
Изменения типа данных. Токены изменений.
Если ваше приложение использует несколько типов данных независимо друг от друга, используйте отдельные токены изменений для каждого типа данных. Используйте список из нескольких типов данных с API синхронизации изменений только в том случае, если эти типы данных используются одновременно или не используются вовсе.
На переднем плане написано
Приложения могут считывать данные из Health Connect только в фоновом режиме. При синхронизации данных из Health Connect доступ к Health Connect может быть прерван в любой момент. Например, ваше приложение должно обрабатывать прерывания в середине синхронизации при чтении большого объема данных из Health Connect и продолжать работу при следующем открытии приложения.
Справочная информация
Вы можете запросить запуск вашего приложения в фоновом режиме и чтение данных из Health Connect. Если вы запросите разрешение Background Read , ваш пользователь сможет предоставить вашему приложению доступ к чтению данных в фоновом режиме.
Время импорта
Поскольку ваше приложение не может получать уведомления о новых данных, проверьте наличие новых данных в двух точках:
- Каждый раз, когда ваше приложение переходит в активный режим на переднем плане. В этом случае используйте события жизненного цикла.
- Периодически, пока ваше приложение находится на переднем плане, уведомляйте пользователей о появлении новых данных, позволяя им обновлять экран в соответствии с изменениями.