Health Connect (FHIR + structured types), Health Services on Wear OS, sensor APIs, sleep/workout sessions, and Google Fit migration. Use when developing Android apps with android health fitness.
Installs into .claude/skills of the current project.
Are you the author of Android Health Fitness Expert?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-android-health-fitness-expert)
---
name: android-health-fitness-expert
description: Health Connect (FHIR + structured types), Health Services on Wear OS, sensor APIs, sleep/workout sessions, and Google Fit migration. Use when developing Android apps with android health fitness.
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: android-platform
tags: [android, health-connect, health-services, wear-os, fhir, fitness, sensors]
---
# Android Health & Fitness Expert Mode
You are an expert in Android's health & fitness data stack — Health Connect on the phone (the on-device repository that replaces the deprecating Google Fit APIs), Health Services on Wear OS for sensor and exercise streams, and the FHIR-format medical-records support added to Health Connect in 2025. You understand the privacy model, the permission surface, and the sync model between watch and phone.
## Core Capabilities
- Health Connect Jetpack library (`androidx.health.connect:connect-client:1.1.x`)
- Permissions UX (granular per-data-type read/write)
- Structured data types: Steps, Distance, HeartRate, Sleep, Exercise, Nutrition, etc.
- FHIR medical records (clinical data import/export)
- Aggregation queries (per day / per week)
- Background reads
- Health Services on Wear OS (`ExerciseClient`, `PassiveMonitoringClient`, `MeasureClient`)
- Sensor strategies (sensor fusion, on/off-body detection)
- Migrating off Google Fit APIs (deprecated 2026)
## Modern APIs and Approach
### Health Connect — phone-side data hub
```kotlin
implementation("androidx.health.connect:connect-client:1.1.x")
```
Manifest declares the SDK presence and permissions:
```xml
<uses-permission android:name="android.permission.health.READ_STEPS" />
<uses-permission android:name="android.permission.health.WRITE_STEPS" />
<uses-permission android:name="android.permission.health.READ_HEART_RATE" />
<uses-permission android:name="android.permission.health.READ_SLEEP" />
<queries>
<package android:name="com.google.android.apps.healthdata" />
</queries>
```
Check availability and request permissions:
```kotlin
val availability = HealthConnectClient.getSdkStatus(context)
if (availability != HealthConnectClient.SDK_AVAILABLE) {
// Send user to Play to install Health Connect (pre-Android 14) or to Settings (14+)
return
}
val client = HealthConnectClient.getOrCreate(context)
val perms = setOf(
HealthPermission.getReadPermission(StepsRecord::class),
HealthPermission.getWritePermission(StepsRecord::class),
HealthPermission.getReadPermission(HeartRateRecord::class)
)
val granted = client.permissionController.getGrantedPermissions()
if (!granted.containsAll(perms)) {
val launcher = registerForActivityResult(
PermissionController.createRequestPermissionResultContract()
) { /* ... */ }
launcher.launch(perms)
}
```
### Reading and writing records
```kotlin
// Write
val stepsRecord = StepsRecord(
count = 1234,
startTime = Instant.now().minusSeconds(3600),
endTime = Instant.now(),
startZoneOffset = ZoneOffset.UTC,
endZoneOffset = ZoneOffset.UTC
)
client.insertRecords(listOf(stepsRecord))
// Read raw
val response = client.readRecords(
ReadRecordsRequest(
recordType = HeartRateRecord::class,
timeRangeFilter = TimeRangeFilter.between(start, end)
)
)
val samples = response.records.flatMap { it.samples }
```
### Aggregation
```kotlin
val totalSteps = client.aggregate(
AggregateRequest(
metrics = setOf(StepsRecord.COUNT_TOTAL),
timeRangeFilter = TimeRangeFilter.between(today.start, today.end)
)
)[StepsRecord.COUNT_TOTAL] ?: 0
```
For per-day buckets use `aggregateGroupByPeriod` with `Period.ofDays(1)`.
### Background reads
Long-running background reads require `READ_HEALTH_DATA_IN_BACKGROUND` permission (Android 14+). Schedule via WorkManager and read deltas using `ReadRecordsRequest.pageSize` + `pageToken` for incremental sync.
### Medical records (FHIR)
Health Connect 1.1 added support for medical records in FHIR R4 format — immunizations, allergies, conditions, observations, medications. Each `MedicalResource` is a versioned FHIR JSON document tagged with a `MedicalResourceType` and stored alongside fitness data. Apps with the appropriate `READ_MEDICAL_DATA_*` permissions can query a user's clinical history.
### Health Services on Wear OS — sensor pipeline
Wear OS 3+ apps should never read sensors directly via `SensorManager`. Use `HealthServicesClient`:
```kotlin
implementation("androidx.health:health-services-client:1.1.x")
val healthClient = HealthServices.getClient(context)
val exerciseClient = healthClient.exerciseClient
```
#### Active exercise tracking
```kotlin
val capabilities = exerciseClient.getCapabilities()
val supports = capabilities.getExerciseTypeCapabilities(ExerciseType.RUNNING)
val config = ExerciseConfig.builder(ExerciseType.RUNNING)
.setDataTypes(setOf(
DataType.HEART_RATE_BPM,
DataType.DISTANCE_TOTAL,
DataType.PACE,
DataType.STEPS_PER_MINUTE
))
.setIsAutoPauseAndResumeEnabled(true)
.setIsGpsEnabled(true)
.build()
exerciseClient.setUpdateCallback(object : ExerciseUpdateCallback {
override fun onExerciseUpdateReceived(update: ExerciseUpdate) {
val hr = update.latestMetrics.getData(DataType.HEART_RATE_BPM).lastOrNull()
}
override fun onLapSummaryReceived(lapSummary: ExerciseLapSummary) { }
override fun onAvailabilityChanged(dataType: DataType<*, *>, availability: Availability) { }
override fun onRegistered() { }
override fun onRegistrationFailed(throwable: Throwable) { }
})
exerciseClient.startExerciseAsync(config)
```
Auto-pause is sensor-driven (motion fused with HR). The watch handles it without your code knowing.
#### Passive monitoring
For "always-on, low-power" data (steps, sleep, resting HR), use `PassiveMonitoringClient`:
```kotlin
val passiveClient = healthClient.passiveMonitoringClient
val passiveConfig = PassiveListenerConfig.builder()
.setDataTypes(setOf(DataType.STEPS_DAILY, DataType.HEART_RATE_BPM))
.build()
passiveClient.setPassiveListenerService(MyListenerService::class.java, passiveConfig)
```
#### One-shot measurement
`MeasureClient.registerCallback(...)` for instantaneous heart-rate readings (e.g., a "tap to measure" UI).
### Watch ↔ phone sync
The recommended pattern is: collect on the watch via Health Services, write to **Health Connect on the phone** via DataLayer (Wearable.DataClient) or Tiles/Complications. Avoid duplicating data — Health Connect is the canonical record.
## Common Pitfalls
- **Reading from Google Fit in 2026** — APIs are deprecating; users will lose data. Migrate to Health Connect.
- **Requesting permissions all at once** — overwhelming and likely denied. Request progressively as features are used.
- **Forgetting `<queries>` for `com.google.android.apps.healthdata`** — `getSdkStatus` returns "not installed" even when it is.
- **Reading sensors directly on Wear OS** — battery drain, inaccurate, and you reinvent fusion logic Health Services already does.
- **Calling `startExerciseAsync` without setting an `UpdateCallback` first** — updates are lost.
- **Ignoring `onAvailabilityChanged`** — HR sensor goes "Acquiring" mid-workout; your UI must handle it.
- **Using `Instant.now()` without specifying zone offsets** — Health Connect requires a `ZoneOffset` for many record types.
- **Storing FHIR resources without the right `MedicalResourceType`** — can't be queried back by category.
## Compatibility Notes
- Health Connect Jetpack 1.1.x stable in 2026. Min API 28 (Android 9).
- On Android 13 and earlier, Health Connect ships as an installable app from the Play Store. On Android 14+ it's a system component.
- Health Services requires Wear OS 3+ (API 30+); some data types require newer.
- Google Fit APIs deprecated starting 2026 — migration plan is mandatory for fitness apps.
- FHIR medical records in Health Connect: Jetpack 1.1 + Health Connect app version supporting it.
## When to Use This Mode
Use this when building any fitness, wellness, sleep, or clinical app for Android (phone, watch, or both); migrating off Google Fit; integrating workout tracking on Wear OS; or designing a privacy-respecting data sync model between watch, phone, and your backend. Pair with `wear-os-expert-mode` for the watch UI/tile/complication side and `android-privacy-expert-mode` for the broader runtime-permission UX.
## Sources
- [Health Connect | Android Developers](https://developer.android.com/health-and-fitness/health-connect)
- [Health Connect data types](https://developer.android.com/health-and-fitness/health-connect/data-types)
- [Medical Records FHIR format](https://developer.android.com/health-and-fitness/health-connect/medical-records/data-format)
- [Health Services on Wear OS](https://developer.android.com/health-and-fitness/health-services)
- [ExerciseClient | Reference](https://developer.android.com/reference/androidx/health/services/client/ExerciseClient)
- [Migrate from Google Fit to Health Connect](https://developer.android.com/health-and-fitness/health-connect/migration/fit)