Skip to content
AF
Health Connect API

PermissionController: requesting, checking and revoking Health Connect permissions

Last verified October 4, 2026 · 5 min read

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.

Covered here:Health Connect

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; this page covers the whole interface and the manifest pieces around it. Sources: the PermissionController reference, the HealthConnectClient reference, the get started guide and the permissions UI guide, 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:

MemberKindReturnsGoogle's description
createRequestPermissionResultContract(providerPackageName: String = DEFAULT_PROVIDER_PACKAGE_NAME)companion functionActivityResultContract<Set<String>, Set<String>>"Creates an ActivityResultContract to request Health permissions."
getGrantedPermissions()suspendSet<String>"Returns a set of all health permissions granted by the user to the calling app."
revokeAllPermissions()suspendUnit"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.

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.

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:

<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.

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 covers the causes.

Frequently asked questions

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.
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.
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.
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.

All 58 questions in Health Connect API →

Keep reading

Elsewhere on the site

Pages that share this one’s concepts and sources, from other sections.

Next steps

Was this page useful?

Independent comparison, last reviewed October 4, 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 health connect api · by AIFitnessAPI