Інтеграція Google Fit для доступу до даних здоров'я в Android
Google Fit API існує з 2014 року та сьогодні перебуває в стані «працює, але краще мігрувати на Health Connect». Google офіційно рекомендує переходити на Health Connect для нових проектів. Все ж таки, Google Fit залишається актуальним для пристроїв на Android 8–13 без підтримки Health Connect, для Wear OS-приложень та для проектів з існуючою базою користувачів. Розглянемо обидва підходи.
Google Fit REST API проти Fitness API
Дві принципово різні точки входу:
Android Fitness API (com.google.android.gms:play-services-fitness) — нативний Java/Kotlin SDK, працює через Google Play Services, потребує OAuth 2.0-аккаунт Google.
Google Fit REST API — HTTP API, підходить для серверної сторони та Flutter/React Native, але потребує власного керування OAuth токенами.
Для нативного Android — завжди Fitness API. REST має смисл тільки якщо дані потрібні на бекенді без участі мобільного пристрою.
Дозволи та OAuth: головний источник проблем
Google Fit потребує двох рівнів дозволів:
-
Android-дозвіл:
android.permission.ACTIVITY_RECOGNITION(Android 10+) -
OAuth scope:
FITNESS_ACTIVITY_READ,FITNESS_BODY_READ,FITNESS_LOCATION_READта ін.
Запросити Android-дозвіл, але не отримати OAuth scope — Fitness API повертає порожні дані без помилки. Це мовчазний сбій, який складно відловити.
val fitnessOptions = FitnessOptions.builder()
.addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
.addDataType(DataType.TYPE_HEART_RATE_BPM, FitnessOptions.ACCESS_READ)
.build()
val account = GoogleSignIn.getAccountForExtension(this, fitnessOptions)
if (!GoogleSignIn.hasPermissions(account, fitnessOptions)) {
GoogleSignIn.requestPermissions(
this,
GOOGLE_FIT_REQUEST_CODE,
account,
fitnessOptions
)
}
Якщо користувач відозве дозвіл через налаштування Google-аккаунту (не через Android Settings), hasPermissions() повертає false при наступному запуску. Це потрібно обробляти — без retry-логіки приложение просто перестане отримувати дані.
Читання даних: HistoryClient та SensorsClient
Історичні дані (кроки, калорії)
val readRequest = DataReadRequest.Builder()
.read(DataType.TYPE_STEP_COUNT_DELTA)
.aggregate(DataType.AGGREGATE_STEP_COUNT_DELTA)
.bucketByTime(1, TimeUnit.DAYS)
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
.build()
Fitness.getHistoryClient(context, account)
.readData(readRequest)
.addOnSuccessListener { response ->
response.buckets.forEach { bucket ->
val steps = bucket.dataSets
.flatMap { it.dataPoints }
.sumOf { it.getValue(Field.FIELD_STEPS).asInt() }
}
}
bucketByTime — ключовий метод для агрегації. Без нього запит повертає кожний крок від кожного джерела (телефон + часи + браслет), що може бути кілька тисяч записів за день.
Дані в реальному часі
SensorsClient для підписи на живі дані:
Fitness.getSensorsClient(context, account)
.add(SensorRequest.Builder()
.setDataType(DataType.TYPE_STEP_COUNT_CUMULATIVE)
.setSamplingRate(10, TimeUnit.SECONDS)
.build(),
onDataPointListener
)
Цей підписчик активний тільки пока приложення на передньому плані. Для фонового трекінгу — RecordingClient.subscribe(), який Google Fit акумулює сам.
Дедуплікація даних з кількох джерел
Це реальна біль: у користувача Apple Watch (через Health) + Google Fit на Android телефоні + Samsung Health — кроки задваиваються та страиваються. Google Fit частково вирішує це через DataSet.getDataSources() — у кожної точки даних є джерело (DataSource). Фільтрація по DataSource.DEVICE дозволяє брати дані тільки від конкретного пристрою.
Повністю надійної дедуплікації немає — це відома проблема екосистеми. Документуємо клієнту очікувані розбіжності та будуємо UI так, щоб користувач міг вибрати приоритетний источник.
Міграція на Health Connect
Для нових пристроїв (Android 14+) Google Fit deprecated на рівні рекомендацій. Стратегія: перевіряємо доступність Health Connect, якщо доступний — використовуємо його, fallback на Google Fit для старих пристроїв:
val healthConnectAvailable = HealthConnectClient.getSdkStatus(context) ==
HealthConnectClient.SDK_AVAILABLE
Терміни
Базова інтеграція Google Fit (кроки, дистанція, калорії) — 4–7 робочих днів. З підтримкою Health Connect, дедупліцюванням та Wear OS — 2–4 тижні.







