Request permissions
How to request, check, enumerate, and revoke health permissions. For why the platforms behave differently here, read Permissions first.
Request permissions
// 1. Ask for exactly what this feature needs.
final permissions = [
HealthDataType.steps.readPermission,
HealthDataType.steps.writePermission,
HealthDataType.weight.readPermission,
HealthPlatformFeature.readHealthDataInBackground.permission,
];
// 2. Request them together — one system prompt, not four.
final results = await connector.requestPermissions(permissions);
// 3. Handle each outcome.
for (final result in results) {
switch (result.status) {
case PermissionStatus.granted:
print('Granted: ${result.permission}');
case PermissionStatus.denied:
print('Denied: ${result.permission}');
case PermissionStatus.unknown:
print('Unknown: ${result.permission} (iOS read permission)');
}
}Decide what "good enough" means
Rarely does a feature need every requested permission. Check the ones that block your UI and let the rest degrade:
final canShowSteps = results.any(
(r) =>
r.permission == HealthDataType.steps.readPermission &&
r.status != PermissionStatus.denied,
);Use any, not where(...).every(...). every returns true on an empty iterable, so a permission missing from the results entirely would read as granted.
Check a single permission
final status = await connector.getPermissionStatus(
HealthDataType.steps.readPermission,
);
switch (status) {
case PermissionStatus.granted:
print('Steps read permission granted');
case PermissionStatus.denied:
print('Steps read permission denied');
case PermissionStatus.unknown:
print('Steps read permission unknown (iOS read)');
}On iOS this only answers for writes
HealthKit restricts access to read-authorization status to protect user privacy, so the SDK reports unknown for every iOS read permission. That is native behavior, not an SDK limitation.
List every granted permission
Android onlytry {
final grantedPermissions = await connector.getGrantedPermissions();
for (final permission in grantedPermissions) {
print('Granted: ${permission.dataType} (${permission.accessType})');
}
} on UnsupportedOperationException {
print('Listing granted permissions is not supported on iOS');
}HealthKit does not allow apps to enumerate grants — that would let an app fingerprint what a user is hiding. This call throws UnsupportedOperationException on iOS.
Revoke all permissions
Android onlytry {
await connector.revokeAllPermissions();
print('Permissions revoked');
} on UnsupportedOperationException {
print('Programmatic revocation is not supported on iOS');
}There is no programmatic revocation on iOS. If your app offers a "disconnect Apple Health" control, point the user to Settings → Health → Data Access & Devices rather than trying to revoke for them.
Exercise routes need two permissions
Route access is layered on top of session access. Route permissions alone do nothing:
final permissions = [
// Foundation — required.
HealthDataType.exerciseSession.readPermission,
HealthDataType.exerciseSession.writePermission,
// Route access on top.
HealthDataType.exerciseSession.readExerciseRoutePermission,
HealthDataType.exerciseSession.writeExerciseRoutePermission,
];
final results = await connector.requestPermissions(permissions);