Skip to content
AFAIFitnessAPI
Integration Guides

How to Integrate Google Health Connect (2026)

Updated July 9, 2026

Google Health Connect gives Android apps on-device access to health and fitness data (steps, heart rate, sleep, calories, and more) from a single OS-managed store. It is not an OAuth cloud API: the user grants access in a system permission sheet and your Kotlin code reads records locally through the androidx.health.connect:connect-client library. It is free and Android-only. The one hard requirement before shipping is a Play Console health-data declaration listing every data type you read or write.

Google Health Connect gives your Android app on-device access to the user's health and fitness data — steps, distance, heart rate, sleep, calories, and dozens of other record types — from a single OS-managed store that other apps (Fitbit, Samsung Health, Google Fit, and more) write into. It is not an OAuth cloud API: there is no client secret, no token exchange, and no server endpoint. The user grants access in a system permission sheet, and your Kotlin code reads records locally through the androidx.health.connect:connect-client library. It is free to use, Android-only, and the main friction is a mandatory Play Console data-type declaration before you can ship.

If you also need iOS, Health Connect is the Android half of a two-platform job — see Apple HealthKit vs. Google Health Connect for how the two compare, because you integrate each SDK natively and there is no shared endpoint between them.

What you'll need

  • An Android app targeting a reasonably recent SDK. On Android 14 and later Health Connect is part of the platform; on older versions it is a separate app the user installs from the Play Store.
  • The Health Connect app present on the device. Your code should check availability and route the user to install or update it if it is missing.
  • The connect-client Jetpack dependency (add it to your module's build.gradle).
  • A Play Console health-data declaration listing every data type you read or write. This is a publishing requirement — plan for it, because reviews can take time.

Verify the library version. The Jetpack library updates frequently. Pin whatever the current stable (or intended alpha) release is from the official docs rather than copying a version string from any tutorial, including this one.

// build.gradle (module) — check the docs for the current version
dependencies {
    implementation "androidx.health.connect:connect-client:<latest-version>"
}

Step 1: Declare your permissions in the manifest

Every health data type you touch is its own permission. Declare each one in AndroidManifest.xml. If you need history older than the default window (covered in Step 5), declare that permission too.

<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.health.READ_STEPS"/>
<uses-permission android:name="android.permission.health.WRITE_STEPS"/>
<!-- Only if you need data older than ~30 days: -->
<uses-permission android:name="android.permission.health.READ_HEALTH_DATA_HISTORY"/>

At runtime you refer to these same permissions as typed strings derived from the record class, not raw manifest names — for example HealthPermission.getReadPermission(StepsRecord::class). Keep the manifest list and your runtime set in sync; a permission requested at runtime but missing from the manifest will not be grantable.

Step 2: Check availability and get the client

Never assume Health Connect is installed. Call HealthConnectClient.getSdkStatus(context) and compare it against HealthConnectClient.SDK_AVAILABLE. Only then create the client with HealthConnectClient.getOrCreate(context). If the SDK is unavailable, send the user to install or update the Health Connect app.

import androidx.health.connect.client.HealthConnectClient

val status = HealthConnectClient.getSdkStatus(context)
val healthConnectClient =
    if (status == HealthConnectClient.SDK_AVAILABLE) {
        HealthConnectClient.getOrCreate(context)
    } else {
        // SDK_UNAVAILABLE or SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED —
        // prompt the user to install or update Health Connect, then stop.
        null
    }

Step 3: Request permissions at runtime

Build the set of permissions you need as typed strings, then request them through the Health Connect permission contract. Unlike a runtime dangerous-permission dialog, this uses PermissionController.createRequestPermissionResultContract() with an Activity Result launcher (or rememberLauncherForActivityResult in Compose). The callback hands you the set of granted permissions, so you check whether it contains everything you asked for.

import androidx.health.connect.client.PermissionController
import androidx.health.connect.client.permission.HealthPermission
import androidx.health.connect.client.records.StepsRecord

val permissions = setOf(
    HealthPermission.getReadPermission(StepsRecord::class),
    HealthPermission.getWritePermission(StepsRecord::class)
)

// Compose example
val requestPermissions = rememberLauncherForActivityResult(
    contract = PermissionController.createRequestPermissionResultContract()
) { granted ->
    if (granted.containsAll(permissions)) {
        // Proceed — every requested permission was granted.
    } else {
        // User denied one or more. Degrade gracefully; do not re-prompt in a loop.
    }
}

// Launch when the user taps "Connect":
// requestPermissions.launch(permissions)

Note the difference from HealthKit here: Health Connect does tell you which permissions were granted, so you can branch on the actual result instead of guessing.

Step 4: Read the user's data

With permission granted, read records inside a coroutine using readRecords(ReadRecordsRequest(...)), scoped by a TimeRangeFilter. Every read returns a list of typed record objects.

import androidx.health.connect.client.request.ReadRecordsRequest
import androidx.health.connect.client.time.TimeRangeFilter
import java.time.Instant

suspend fun readSteps(start: Instant, end: Instant): List<StepsRecord> {
    val client = healthConnectClient ?: return emptyList()
    val response = client.readRecords(
        ReadRecordsRequest(
            StepsRecord::class,
            timeRangeFilter = TimeRangeFilter.between(start, end)
        )
    )
    return response.records
}

For a step total, prefer aggregate() with StepsRecord.COUNT_TOTAL over summing raw records yourself. Multiple apps can write steps for the same window, and raw reads will double-count overlapping sources; the aggregate query de-duplicates for you.

import androidx.health.connect.client.request.AggregateRequest

suspend fun readStepTotal(start: Instant, end: Instant): Long {
    val client = healthConnectClient ?: return 0L
    val response = client.aggregate(
        AggregateRequest(
            metrics = setOf(StepsRecord.COUNT_TOTAL),
            timeRangeFilter = TimeRangeFilter.between(start, end)
        )
    )
    return response[StepsRecord.COUNT_TOTAL] ?: 0L
}

Step 5: Handle the 30-day history limit

By default, a freshly granted app can read only data from up to 30 days before the first permission grant. Reads that reach further back will error out. To read older history you must request the dedicated history permission — as of 2026 the constant is HealthPermission.PERMISSION_READ_HEALTH_DATA_HISTORY (verify the exact name and its READ_HEALTH_DATA_HISTORY manifest string against current docs, as these have shifted). This is separate from the background-read permission, which controls whether you can read while your app is backgrounded.

One more sharp edge: reinstalling your app resets the 30-day window, so a returning user's deep history becomes unavailable again until they re-grant (and you hold the history permission). Design onboarding so a user without the history permission still gets a useful recent view.

Step 6: Complete the Play Console declaration and ship

Before your app can be published with Health Connect access, you must fill out the health-data declaration in the Play Console, listing every data type you read and write and justifying each. This is a policy gate, not a formality — omitting a type you actually read, or requesting types you cannot justify, causes rejections. Do this early so review time does not block your release.

Production notes to plan for:

  • Availability drift. Users can uninstall Health Connect or revoke a permission at any time. Re-check getSdkStatus and handle empty or error responses on every read, not just at first launch.
  • Grant the minimum. Request only the record types your feature needs. A shorter declaration is easier to justify in review and easier for users to trust.
  • Data types are typed classes. StepsRecord is one of dozens (HeartRateRecord, SleepSessionRecord, TotalCaloriesBurnedRecord, and more). Each read and write permission is per-class, so scope your request set deliberately.
  • Backgrounded reads need their own permission. If you sync in the background, add the background-read permission on top of your data-type permissions.

Once step and workout data is flowing, wiring it into a live tracking experience is the next step — add AI workout tracking on Android with Kotlin walks through turning that data (plus on-device pose tracking) into rep counting and form feedback. For the broader landscape of device and health-data sources, see the wearable data APIs overview.

Frequently asked questions

Does Google Health Connect use OAuth or an API key?
No. Health Connect is on-device and permission-based, not a cloud API. There is no client secret, token exchange, or server endpoint. The user grants access in a system permission sheet and your app reads from a local, OS-managed store through the connect-client library.
Do I need approval to use Health Connect?
There is no OAuth partner-approval step to read data during development. However, to publish an app that uses Health Connect you must complete the Play Console health-data declaration listing every data type you read or write, and requesting types you cannot justify can cause review rejections. Treat that declaration as a required gate before release.
Do I need a separate permission to read Health Connect data in the background?
Yes. The per-record-type permissions you request cover foreground reads only; syncing while your app is backgrounded needs the dedicated background-read permission on top of them, and that is separate again from the historical-read permission. Declare it in the manifest and include it in your runtime request set like any other Health Connect permission, and expect to justify it in the Play Console health-data declaration, since background access draws more scrutiny than a foreground read. Verify the current constant and manifest string in the docs, as these names have shifted between releases.
Which library and version should I use?
Use the androidx.health.connect:connect-client Jetpack library. It updates frequently, so pin the current stable or intended release from the official Health Connect docs rather than copying a version from a tutorial. The class and method names such as HealthConnectClient.getOrCreate and readRecords are stable across recent versions.
Is Health Connect available on all Android devices?
No. On Android 14 and later it is part of the platform, while on older versions it is a separate app the user installs from the Play Store. Always check HealthConnectClient.getSdkStatus and prompt the user to install or update Health Connect when it is unavailable, rather than assuming it is present.

Keep reading

Independent comparison, last reviewed July 9, 2026. Pricing, rate limits, and feature availability change often — confirm current details in each provider’s official documentation before you commit. Product and company names are trademarks of their respective owners; AIFitnessAPI is not affiliated with, endorsed by, or sponsored by any product listed here.

← All integration guides · by AIFitnessAPI