Это руководство совместимо с платформой "Здоровье и спорт" версии 1.1.0-alpha12 или более поздней.
У большинства приложений, интегрированных с платформой "Здоровье и спорт", есть собственное хранилище данных, которое служит источником достоверной информации. Платформа "Здоровье и спорт" позволяет синхронизировать данные в приложении.
В зависимости от архитектуры приложения процесс синхронизации может включать некоторые или все из следующих действий:
- Передавайте новые или обновленные данные из хранилища данных приложения в сервис "Здоровье и спорт".
- Извлеките изменения данных из Здоровья и спорта в хранилище данных вашего приложения.
- Удаляйте данные из сервиса "Здоровье и спорт", когда они удаляются из хранилища данных вашего приложения.
В каждом случае убедитесь, что процесс синхронизации поддерживает согласованность данных на платформе "Здоровье и спорт" и в хранилище данных вашего приложения.
Передача данных в приложение "Здоровье и спорт"
Первая часть процесса синхронизации – передача данных из хранилища вашего приложения в хранилище платформы "Здоровье и спорт".
Подготовка данных
Обычно записи в хранилище данных приложения содержат следующие сведения:
- Уникальный ключ, например
UUID. - Версия или временная метка.
При синхронизации данных с платформой "Здоровье и спорт" определяйте и передавайте только те данные, которые были добавлены, обновлены или удалены с момента последней синхронизации.
Запись данных в Здоровье и спорт
Чтобы передать данные в сервис "Здоровье и спорт", выполните следующие действия:
- Получите список новых, обновленных или удаленных записей из хранилища данных приложения.
- Для каждой записи создайте объект
Record, соответствующий типу данных. Например, создайте объектWeightRecordдля данных, связанных с весом. Укажите объект
Metadataдля каждогоRecord. В том числе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.activelyRecorded( 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))
Обновляйте данные в сервисе "Здоровье и спорт" с помощью
insertRecords. Обновление данных означает, что любые существующие данные в сервисе "Здоровье и спорт" перезаписываются, если значенияclientRecordIdсуществуют в хранилище данных сервиса "Здоровье и спорт", а значениеclientRecordVersionвыше существующего. В противном случае данные будут записаны как новые.healthConnectClient.insertRecords(arrayListOf(record))
Чтобы узнать, как лучше всего передавать данные, ознакомьтесь с рекомендациями по записи данных.
Хранить идентификаторы платформы "Здоровье и спорт"
Если ваше приложение также считывает данные из Health Connect, сохраняйте id Health Connect для записей после их обновления или вставки. Этот id нужен для обработки удалений при получении изменений данных из сервиса "Здоровье и спорт".
Функция insertRecords возвращает объект InsertRecordsResponse, который содержит список значений id.
Используйте ответ, чтобы получить идентификаторы записей и сохранить их.
val response = healthConnectClient.insertRecords(listOf(record)) for (recordId in response.recordIdsList) { // Store recordId to your app's datastore }
Получение данных из сервиса "Здоровье и спорт"
Вторая часть процесса синхронизации – извлечение изменений данных из платформы "Здоровье и спорт" в хранилище данных приложения. Изменения данных могут включать обновления и удаления.
Как получить токен изменений
Чтобы получить список изменений, которые нужно извлечь из платформы "Здоровье и спорт", вашему приложению необходимо отслеживать токены Changes. Их можно использовать при запросе изменений, чтобы получить список изменений данных и новый токен изменений для следующего раза.
Чтобы получить токен Changes, вызовите getChangesToken и укажите нужные типы данных.
val changesToken = healthConnectClient.getChangesToken( ChangesTokenRequest(recordTypes = setOf(WeightRecord::class)) )
Проверьте, изменились ли данные
Получив токен Changes, используйте его, чтобы получить все изменения (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, как описано в разделе Как хранить идентификаторы платформы "Здоровье и спорт".
Как удалить данные из сервиса "Здоровье и спорт"
Если пользователь удаляет свои данные из вашего приложения, убедитесь, что они также удаляются из сервиса "Здоровье и спорт". Для этого используйте deleteRecords. Он принимает тип записи и список значений id и clientRecordId, что позволяет удобно удалять несколько данных за раз. Также доступен альтернативный метод deleteRecords, который принимает timeRangeFilter.
Синхронизация с носимыми устройствами с низкой задержкой.
Чтобы синхронизировать данные с носимого фитнес-устройства с платформой "Здоровье и спорт" с низкой задержкой, используйте CompanionDeviceService. Этот подход работает для устройств, которые поддерживают уведомления или индикаторы BLE GATT и предназначены для Android 8.0 (уровень API 26) или более поздней версии. CompanionDeviceService позволяет вашему приложению получать данные от носимых устройств и записывать их в сервис "Здоровье и спорт", даже если приложение не запущено. Дополнительную информацию о рекомендациях по использованию BLE см. в разделе Обзор Bluetooth с низким энергопотреблением.
Как связать устройство
Сначала в приложении нужно выполнить однократную процедуру связывания носимого устройства с приложением с помощью CompanionDeviceManager. Это предоставит вашему приложению необходимые разрешения для взаимодействия с устройством. Подробнее о подключении дополнительных устройств…
Объявите службу в манифесте
Затем объявите 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. Новые данные сразу записываются на платформе "Здоровье и спорт".
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из приложения "Здоровье и спорт". - Запросите у платформы "Здоровье и спорт" записи, начиная с определенной временной метки, а затем вставьте или обновите их в хранилище данных приложения.
- Запросите токен изменений, чтобы зарезервировать его для следующего раза.
Рекомендуемые стратегии управления изменениями
Если ваше приложение получает недействительные или просроченные токены Changes, мы рекомендуем следующие стратегии управления в зависимости от их применения в вашей логике:
- Чтение и дедупликация всех данных. Это наиболее оптимальная стратегия.
- Сохраняйте временную метку последнего считывания данных из Здоровья и спорта.
- По истечении срока действия токена повторно считайте все данные, начиная с самой последней временной метки или за последние 30 дней. Затем удалите дубликаты, сравнив новые данные с ранее прочитанными по идентификаторам.
- Рекомендуем реализовать идентификаторы клиентов, поскольку они необходимы для обновления данных.
- Считывать только данные, добавленные после последней временной метки. Это приводит к некоторым расхождениям в данных во время истечения срока действия токена изменений, но период времени короче и может занять от нескольких часов до пары дней.
- Сохраняйте временную метку последнего считывания данных из Здоровья и спорта.
- Когда срок действия токена истечет, прочитайте все данные, начиная с этой временной метки.
- Удалить, а затем прочитать данные за последние 30 дней. Это больше похоже на то, что происходит при первой интеграции.
- Удалить все данные, считанные приложением из Health Connect за последние 30 дней.
- После удаления прочитайте все эти данные снова.
- Прочитайте данные за последние 30 дней без дедупликации. Это наименее предпочтительный вариант, поскольку в этом случае пользователи будут видеть повторяющиеся данные.
- Удалить все данные, считанные приложением из Здоровье и спорт за последние 30 дней.
- Разрешить повторяющиеся записи.
Токены изменений типа данных
Если ваше приложение использует несколько типов данных независимо друг от друга, используйте отдельные токены изменений для каждого типа данных. Используйте список из нескольких типов данных с Changes Sync API, только если эти типы данных используются вместе или не используются вообще.
Чтение на переднем плане
Приложения могут считывать данные из сервиса "Здоровье и спорт", только когда они работают в активном режиме. При синхронизации данных с платформы "Здоровье и спорт" доступ к ней может быть прерван в любой момент. Например, ваше приложение должно справляться с прерываниями в середине синхронизации при чтении большого объема данных из Здоровья и спорта и продолжать работу при следующем открытии приложения.
Чтение в фоновом режиме
Вы можете запросить разрешение на работу приложения в фоновом режиме и чтение данных из Здоровья и спорта. Если вы запрашиваете разрешение Background Read, пользователь может разрешить приложению считывать данные в фоновом режиме.
Импорт временных меток
Поскольку приложение не может получать уведомления о новых данных, проверяйте их наличие в двух случаях:
- Каждый раз, когда приложение становится активным на переднем плане. В этом случае используйте события жизненного цикла.
- Периодически, пока приложение открыто. Уведомляйте пользователей о появлении новых данных, чтобы они могли обновить экран и увидеть изменения.