---
title: "PermissionController: requesting, checking and revoking Health Connect permissions"
canonical: "https://aifitnessapi.com/health-connect-api/permissioncontroller-request-permissions"
cluster: "Health Connect API"
primary_query: "PermissionController.createRequestPermissionResultContract"
last_reviewed: "2026-10-04"
description: "PermissionController in Health Connect: createRequestPermissionResultContract, getGrantedPermissions, revokeAllPermissions and the rationale activity."
publisher: "AIFitnessAPI — independent, not sponsored"
cite_as: "\"PermissionController: requesting, checking and revoking Health Connect permissions\", AIFitnessAPI, https://aifitnessapi.com/health-connect-api/permissioncontroller-request-permissions"
---

# PermissionController: requesting, checking and revoking Health Connect permissions

> PermissionController is the Health Connect Jetpack interface for permissions, reached through healthConnectClient.permissionController, with a companion function, createRequestPermissionResultContract(), that returns an ActivityResultContract taking the set of permission strings you ask for and returning the set the user granted. getGrantedPermissions() returns every health permission the user has granted your app, and revokeAllPermissions() withdraws them all, although Google warns the change isn't immediately reflected in Health Connect without an app restart. Because the permission screen links to your privacy policy, the manifest also needs an activity for ACTION_SHOW_PERMISSIONS_RATIONALE and, on Android 14 and later, an activity alias for VIEW_PERMISSION_USAGE.

- Canonical: https://aifitnessapi.com/health-connect-api/permissioncontroller-request-permissions
- Last reviewed: 2026-10-04
- Publisher: AIFitnessAPI (https://aifitnessapi.com) — independent, not sponsored
- Cite as: "PermissionController: requesting, checking and revoking Health Connect permissions", AIFitnessAPI, https://aifitnessapi.com/health-connect-api/permissioncontroller-request-permissions

---

Health Connect permissions are requested through `PermissionController`, whose contract, in Google's words, "displays the Health Connect permissions screen." The first request is part of setup and is shown in the [Google Health Connect integration guide](/integrate/google-health-connect); this page covers the whole interface and the manifest pieces around it. Sources: the [`PermissionController` reference](https://developer.android.com/reference/kotlin/androidx/health/connect/client/PermissionController), the [`HealthConnectClient` reference](https://developer.android.com/reference/kotlin/androidx/health/connect/client/HealthConnectClient), the [get started guide](https://developer.android.com/health-and-fitness/health-connect/get-started) and the [permissions UI guide](https://developer.android.com/health-and-fitness/health-connect/ui/permissions), all fetched October 4, 2026.

## The interface

`PermissionController` is "Interface for operations related to permissions", and `HealthConnectClient.permissionController` gives you the instance ("Access operations related to permissions."). It has three members:

| Member | Kind | Returns | Google's description |
| --- | --- | --- | --- |
| `createRequestPermissionResultContract(providerPackageName: String = DEFAULT_PROVIDER_PACKAGE_NAME)` | companion function | `ActivityResultContract<Set<String>, Set<String>>` | "Creates an `ActivityResultContract` to request Health permissions." |
| `getGrantedPermissions()` | suspend | `Set<String>` | "Returns a set of all health permissions granted by the user to the calling app." |
| `revokeAllPermissions()` | suspend | `Unit` | "Revokes all previously granted `HealthPermission` by the user to the calling app." |

The reference labels the interface, `createRequestPermissionResultContract` and `revokeAllPermissions` "Added in 1.1.0"; `getGrantedPermissions` carries no label of its own. The two suspend functions list `RemoteException`, `IOException` and `IllegalStateException` ("If service is not available"). The optional `providerPackageName` is documented only as the "Optional provider package name to request health permissions from." For tests, the reference names `FakePermissionController`, "A fake `PermissionController` that enables full control of permissions in tests"; test setup is covered in [Health Connect test data](/test/health-connect-test-data).

## Check first, then request

Google's guide gives the order: "Use `getGrantedPermissions` to see if your app already has the required permissions granted. If not, use `createRequestPermissionResultContract` to request those permissions. This displays the Health Connect permissions screen." Every permission you request must already be declared: "Make sure that the permissions in the set are declared in your Android manifest first." The permission strings for each record type are listed on the [Health Connect permissions page](/health-connect/permissions).

```kotlin
class ConnectActivity : ComponentActivity() {
    private val wanted = setOf(
        HealthPermission.getReadPermission(StepsRecord::class),
        HealthPermission.getWritePermission(StepsRecord::class)
    )

    private val requestPermissions =
        registerForActivityResult(PermissionController.createRequestPermissionResultContract()) { granted ->
            if (granted.containsAll(wanted)) startSync()          // your code
            else showPartialAccess(wanted - granted)              // your code
        }

    fun onConnectTapped(client: HealthConnectClient) {
        lifecycleScope.launch {
            val granted = client.permissionController.getGrantedPermissions()
            if (granted.containsAll(wanted)) startSync() else requestPermissions.launch(wanted)
        }
    }
}
```

The contract's output is a set of granted permission strings; Google's samples test it with `contains` and `containsAll` against what they asked for. Google does not document whether that set covers only the permissions requested in this launch or everything granted so far, so compare against your own request, or call `getGrantedPermissions()` afterwards. Grants can change at any time: "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."

## When the user says no twice

The permissions UI guide: "If the user selects Cancel on the permissions request screen twice in a row, your app should present the user with a screen similar to the following", and "Once this screen is displayed, users need to re-enable permissions from within the Health Connect Settings menu." Google does not document what a further launch of the contract does in that state, so do not re-prompt in a loop. To send users to Health Connect, `HealthConnectClient.getHealthConnectManageDataIntent(context)` returns an "Intent to open Health Connect data management screen on this phone", and `HealthConnectClient.ACTION_HEALTH_CONNECT_SETTINGS` is the "Intent action to open Health Connect settings on this phone." Both are labelled "Added in 1.1.0".

## revokeAllPermissions

`revokeAllPermissions()` withdraws every health permission your app holds. It fits a "disconnect from Health Connect" switch, with a caveat from the permissions UI guide: "If you programmatically revoke permissions using `revokeAllPermissions()`, explain to the user that the changes aren't immediately reflected in Health Connect without an app restart. To avoid a confusing user experience, give users the option to go to Health Connect settings to revoke permissions there."

## The rationale activity

Health Connect's permission screen links to your privacy policy, and the link opens an activity in your app. The get started guide: "Your Android manifest needs to have an Activity that displays your app's privacy policy, which is your app's rationale of the requested permissions, describing how the user's data is used and handled." Google's manifest, with one entry for Android 13 and lower and an alias for Android 14 and later:

```xml
<activity
    android:name=".PermissionsRationaleActivity"
    android:exported="true">
  <intent-filter>
    <action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
  </intent-filter>
</activity>

<activity-alias
    android:name="ViewPermissionUsageActivity"
    android:exported="true"
    android:targetActivity=".PermissionsRationaleActivity"
    android:permission="android.permission.START_VIEW_PERMISSION_USAGE">
  <intent-filter>
    <action android:name="android.intent.action.VIEW_PERMISSION_USAGE" />
    <category android:name="android.intent.category.HEALTH_PERMISSIONS" />
  </intent-filter>
</activity-alias>
```

Google adds: "The activity must display the same privacy policy you provide for your app in the Google Play Console." What Google Play checks around that policy and the data-type declaration is covered in [Google Play's Health Connect publishing requirements](/compliance/google-play-health-connect-publishing-requirements).

## Pitfalls

- **Requesting permissions you did not declare.** Google's guide requires every requested permission to be in the manifest first, and the manifest list to match the data types declared in the Play Console.
- **Checking once at startup.** A permission granted yesterday may be revoked today. Check before each use.
- **Treating a partial grant as failure.** On background reads, Google's read guide says the app "should still run, and it should perform as many tasks as it can with the permissions that the user granted." The same approach suits any partial grant.
- **Expecting `revokeAllPermissions()` to show up immediately.** Google says it isn't reflected in Health Connect without an app restart.
- **A missing rationale activity.** Google's get started guide says the manifest "needs to have" it: the `ACTION_SHOW_PERMISSIONS_RATIONALE` intent is sent "when the user clicks on the privacy policy link in the Health Connect permissions screen", and without the activity it has nothing to open.
- **Reading a `SecurityException` as "no data".** A call made without the right permission throws; [Health Connect SecurityException](/fix/health-connect-securityexception) covers the causes.

## FAQ

### What does createRequestPermissionResultContract return in Health Connect?

An ActivityResultContract whose input is the set of permission strings you request and whose output is a set of granted permission strings. Google's reference declares it as ActivityResultContract of Set of String to Set of String, and its samples register it with registerForActivityResult or rememberLauncherForActivityResult, then check the returned set with contains or containsAll. Google does not say whether the output includes permissions granted before this launch.

[Permalink](https://aifitnessapi.com/health-connect-api/permissioncontroller-request-permissions#faq-1)

### Does revokeAllPermissions take effect immediately in Health Connect?

Not from the user's point of view. Google's permissions UI guide says that if you revoke permissions programmatically with revokeAllPermissions(), you should explain to the user that the changes aren't immediately reflected in Health Connect without an app restart, and that offering a route to Health Connect settings avoids a confusing experience. The reference describes the call as revoking all previously granted health permissions for the calling app.

[Permalink](https://aifitnessapi.com/health-connect-api/permissioncontroller-request-permissions#faq-2)

### Why does a Health Connect app need an activity for ACTION_SHOW_PERMISSIONS_RATIONALE?

Because the Health Connect permission screen links to your privacy policy and opens it inside your app. Google's get started guide says the manifest needs an activity that displays the privacy policy, describing how the user's data is used and handled, declared for the ACTION_SHOW_PERMISSIONS_RATIONALE intent, plus an activity alias for VIEW_PERMISSION_USAGE with the HEALTH_PERMISSIONS category on Android 14 and later.

[Permalink](https://aifitnessapi.com/health-connect-api/permissioncontroller-request-permissions#faq-3)

### What happens after a user cancels the Health Connect permission screen twice?

Google's permissions UI guide says that when the user selects Cancel on the permission request screen twice in a row, your app should show a screen explaining the situation, and that from then on users need to re-enable permissions from within the Health Connect settings menu. HealthConnectClient.getHealthConnectManageDataIntent and ACTION_HEALTH_CONNECT_SETTINGS give you ways to send them there.

[Permalink](https://aifitnessapi.com/health-connect-api/permissioncontroller-request-permissions#faq-4)
