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.
Scanned 9/8/2026
Install to Claude Code
npx -y skills add anubhavg-icpl/vibe --skill android-health-fitness-expert --agent claude-codeInstalls 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 automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-android-health-fitness-expert)More formats (shields.io, HTML) on the badges page.
---
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)
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!