---
title: "READ_HEALTH_DATA_IN_BACKGROUND: reading Health Connect data from a background worker"
canonical: "https://aifitnessapi.com/health-connect-api/read-health-data-in-background"
cluster: "Health Connect API"
primary_query: "READ_HEALTH_DATA_IN_BACKGROUND"
last_reviewed: "2026-10-04"
description: "How Health Connect background reads work per Google's docs: the READ_HEALTH_DATA_IN_BACKGROUND permission, the feature check and the WorkManager worker."
publisher: "AIFitnessAPI — independent, not sponsored"
cite_as: "\"READ_HEALTH_DATA_IN_BACKGROUND: reading Health Connect data from a background worker\", AIFitnessAPI, https://aifitnessapi.com/health-connect-api/read-health-data-in-background"
---

# READ_HEALTH_DATA_IN_BACKGROUND: reading Health Connect data from a background worker

> Health Connect only lets an app read while it is in the foreground unless the user grants android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND, which Google describes as an extra permission that lets you "read data after the user or system places your app in the background." It depends on the Health Connect version installed, so check HealthConnectFeatures.FEATURE_READ_HEALTH_DATA_IN_BACKGROUND with getFeatureStatus() first, then request it from the foreground with the usual permission contract. Google's documented pattern is a periodic WorkManager CoroutineWorker that calls readRecords; there is no callback, because Google says apps cannot be notified of new data.

- Canonical: https://aifitnessapi.com/health-connect-api/read-health-data-in-background
- Last reviewed: 2026-10-04
- Publisher: AIFitnessAPI (https://aifitnessapi.com) — independent, not sponsored
- Cite as: "READ_HEALTH_DATA_IN_BACKGROUND: reading Health Connect data from a background worker", AIFitnessAPI, https://aifitnessapi.com/health-connect-api/read-health-data-in-background

---

Health Connect assumes your app reads while the user is looking at it. Reading from a scheduled job, after the user has left the app, is a separate permission with its own feature check, and Google documents one pattern for it. This page covers that permission, the check, and the worker, according to Google's Health Connect guides and the Jetpack reference. Setup, the SDK dependency and the basic permission flow are in the [Health Connect integration guide](/integrate/google-health-connect).

## What Google says reads are allowed to do

Google's "Read raw data" guide splits reads in two:

- "Foreground reads: You can normally read data from Health Connect when your app is in the foreground. In these cases, you may consider using a foreground service to run this operation in case the user or system places your app in the background during a read operation."
- "Background reads: By requesting an extra permission from the user, you can read data after the user or system places your app in the background."

The sync guide puts the default even more plainly: "Apps can only read data from Health Connect while they are in the foreground." Without the extra permission, a sync that starts in the foreground can be cut off when the user switches away, and Google tells you to expect that: "your app must handle interruptions midway through a sync when reading a large amount of data from Health Connect, and continue the next time the app is opened."

## The permission, by each of its names

| Where | Name | What the docs say |
| --- | --- | --- |
| Manifest | `android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND` | Google's data-types page lists it among the additional read permissions that "must be declared separately from data type permissions". |
| Jetpack | `HealthPermission.PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND` | "A permission to read data in background." |
| Framework | `HealthPermissions.READ_HEALTH_DATA_IN_BACKGROUND` | "Allows an application to read health data (of any type) in background." Added in API level 35, also in U Extensions 13. Protection level: dangerous. |

It covers every data type at once. You still need the ordinary read permission for each type you read; the background permission only changes when you are allowed to use them. The Jetpack reference warns: "An attempt to read data in background without this permission may result in an error." The reference page shows no "Added in" version for the constant itself; the `HealthPermission` class is listed as added in 1.1.0.

## Check the feature before you ask for it

Background reads depend on the Health Connect build on the device. The Jetpack reference says: "This feature is dependent on the version of HealthConnect installed on the device. To check if it's available call `HealthConnectFeatures.getFeatureStatus` and pass `HealthConnectFeatures.FEATURE_READ_HEALTH_DATA_IN_BACKGROUND` as an argument."

`FEATURE_READ_HEALTH_DATA_IN_BACKGROUND` is the constant `1`, added in 1.1.0, and the call returns `FEATURE_STATUS_AVAILABLE` or `FEATURE_STATUS_UNAVAILABLE`. How the check works for every flag is covered on the [getFeatureStatus page](/health-connect-api/getfeaturestatus-feature-availability). Google's availability guide adds that "users using the APK (on Android 13 and lower) can't use the system module features that are only available on devices running Android 14 or higher." It does not say, on the pages fetched for this article, whether background reads is one of those system-module features, so let the runtime check decide.

## Request it while the user is in the app

The permission is requested through the same contract as any other Health Connect permission, `PermissionController.createRequestPermissionResultContract()`. Google's reference sample only launches the request when the feature is available:

```kotlin
val requestPermission = activity.registerForActivityResult(
    PermissionController.createRequestPermissionResultContract()
) { granted: Set<String> ->
    if (HealthPermission.PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND in granted) {
        // background reads are allowed from now on
    } else {
        // keep to foreground reads
    }
}

if (healthConnectClient.features.getFeatureStatus(
        HealthConnectFeatures.FEATURE_READ_HEALTH_DATA_IN_BACKGROUND
    ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE
) {
    requestPermission.launch(setOf(HealthPermission.PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND))
}
```

A comment in the Jetpack reference's background-read sample states the order: "The permission should be requested and granted beforehand when the app is in foreground". Declare it in the manifest alongside the type permissions; the get-started guide says to nest `<uses-permission>` tags "within the `<manifest>` tags". The whole request flow is on the [PermissionController page](/health-connect-api/permissioncontroller-request-permissions).

## The WorkManager pattern Google documents

Google's background-read example uses a `CoroutineWorker` scheduled as unique periodic work, enqueued only after the feature check. This sketch keeps Google's structure and adds the permission check its reference sample performs before reading:

```kotlin
class ScheduleWorker(appContext: Context, params: WorkerParameters) :
    CoroutineWorker(appContext, params) {

    override suspend fun doWork(): Result {
        val client = HealthConnectClient.getOrCreate(applicationContext)
        val granted = client.permissionController.getGrantedPermissions()
        if (HealthPermission.PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND !in granted) {
            return Result.success() // nothing to do until the user grants it
        }
        val end = Instant.now()
        val response = client.readRecords(
            ReadRecordsRequest(
                StepsRecord::class,
                timeRangeFilter = TimeRangeFilter.between(end.minus(Duration.ofHours(1)), end)
            )
        )
        // your code: store response.records
        return Result.success()
    }
}

fun enqueueBackgroundReadWorker(context: Context, client: HealthConnectClient) {
    if (client.features.getFeatureStatus(
            HealthConnectFeatures.FEATURE_READ_HEALTH_DATA_IN_BACKGROUND
        ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE
    ) {
        val request = PeriodicWorkRequestBuilder<ScheduleWorker>(1, TimeUnit.HOURS).build()
        WorkManager.getInstance(context).enqueueUniquePeriodicWork(
            "read_health_connect",
            ExistingPeriodicWorkPolicy.KEEP,
            request
        )
    }
}
```

The one-hour interval is what Google's sample uses, not a documented requirement. For a sum such as steps, the worker should call [aggregate](/health-connect-api/aggregate-request) rather than add up raw records; Google's read guide says to use `aggregate()` for cumulative types "to avoid double counting from multiple sources". To fetch only what changed since the last run, keep a changes token and call [getChanges](/health-connect-api/getchanges-incremental-sync) from the worker instead of rereading a window.

## There is no push to wake the worker

Health Connect does not call your app when data arrives. The sync guide says so directly: "As your app can't get notified of new data, check for new data at two points", namely when the app comes to the foreground and periodically while it stays there. The background permission lets a scheduled job do the same polling while the app is closed; it does not add a callback. How that compares with HealthKit's observer queries is on the [HealthKit to Health Connect equivalents page](/health-connect-api/healthkit-vs-health-connect-api-equivalents), and the general design is in [background sync](/architecture/background-sync).

## Pitfalls

- **Routes from other apps stay foreground-only.** Google's exercise-routes guide: "Your app can't read exercise route data created by other apps when it runs in the background." The read returns `ExerciseRouteResult.ConsentRequired` instead, even with "Always allow" access. See [exercise route consent](/health-connect-api/exercise-route-consent).
- **Check the grant on every run.** Google's get-started guide: "Because users can grant or revoke permissions at any time, your app needs to check for permissions every time before using them and handle scenarios where permission is lost." A worker scheduled last month cannot assume the grant still holds.
- **Partial grants are normal.** Google's note: "If the user doesn't grant all of the permissions that are required for background reads, your app should still run, and it should perform as many tasks as it can with the permissions that the user granted."
- **The manifest sample puts the tag in the wrong parent.** Google's background-read snippet shows the `<uses-permission>` line inside `<application>`; the get-started guide says to nest permissions within `<manifest>`. Follow the get-started guide.
- **Background reads are still rate limited.** Google's read guide asks you to "be careful to avoid rate-limiting concerns" when paging through large reads. A worker that rereads a long window every hour is the easiest way to hit the limit; [Health Connect rate limits](/fix/health-connect-rate-limit) covers the error.
- **The 30-day history limit still applies.** Background access does not extend how far back you can read. That is [READ_HEALTH_DATA_HISTORY](/health-connect-api/read-health-data-history), requested separately.

## FAQ

### Does Health Connect let an Android app read health data while it is in the background?

Only with an extra permission. Google's sync guide says apps can only read data from Health Connect while they are in the foreground, and its read guide says that by requesting an additional permission, android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND, you can read data after the user or system places your app in the background. The ordinary per-type read permissions are still needed alongside it.

[Permalink](https://aifitnessapi.com/health-connect-api/read-health-data-in-background#faq-1)

### How do I check whether background reads are supported before requesting READ_HEALTH_DATA_IN_BACKGROUND?

Call healthConnectClient.features.getFeatureStatus(HealthConnectFeatures.FEATURE_READ_HEALTH_DATA_IN_BACKGROUND) and compare the result with FEATURE_STATUS_AVAILABLE. Google's reference says the feature depends on the version of Health Connect installed on the device, and its samples only launch the permission request when the check returns available.

[Permalink](https://aifitnessapi.com/health-connect-api/read-health-data-in-background#faq-2)

### What does Google recommend for running Health Connect reads on a schedule?

A periodic WorkManager job. Google's background-read example defines a CoroutineWorker that gets a HealthConnectClient in doWork, and enqueues it with PeriodicWorkRequestBuilder and enqueueUniquePeriodicWork using ExistingPeriodicWorkPolicy.KEEP, only after confirming the background-read feature is available. Its sample uses a one-hour interval, which is an example rather than a documented requirement.

[Permalink](https://aifitnessapi.com/health-connect-api/read-health-data-in-background#faq-3)

### Can a background worker read exercise routes recorded by other apps?

No. Google's exercise-routes guide says your app cannot read route data created by other apps while it runs in the background, and that Health Connect returns ExerciseRouteResult.ConsentRequired in that case even if the user gave Always allow access to routes. Google recommends requesting routes when the user is actively using your app.

[Permalink](https://aifitnessapi.com/health-connect-api/read-health-data-in-background#faq-4)
