Quick start
This flow checks availability, creates the connector, requests access, writes a record, and reads it back.
Create a connector
import 'package:health_connector/health_connector.dart';
Future<HealthConnector> createConnector() async {
final status = await HealthConnector.getHealthPlatformStatus();
if (status != HealthPlatformStatus.available) {
throw StateError('Health platform is not available: $status');
}
return HealthConnector.create();
}Logging is disabled unless you configure a processor. During development, opt in explicitly:
final connector = await HealthConnector.create(
const HealthConnectorConfig(
loggerConfig: HealthConnectorLoggerConfig(
logProcessors: [PrintLogProcessor()],
),
),
);Request permissions
final results = await connector.requestPermissions([
HealthDataType.steps.readPermission,
HealthDataType.steps.writePermission,
]);On iOS, read permission results are unknown even when access is available. Apple intentionally prevents apps from determining whether the user denied read access. Treat an empty read response as a valid result, not proof of denial.
Write steps
final now = DateTime.now();
final record = StepsRecord(
id: HealthRecordId.none,
startTime: now.subtract(const Duration(hours: 1)),
endTime: now,
count: Number(2400),
metadata: Metadata.automaticallyRecorded(
device: Device.fromType(DeviceType.phone),
),
);
final ids = await connector.writeRecords([record]);New records use HealthRecordId.none; the native health store assigns the persisted identifier.
Read typed records
final response = await connector.readRecords(
HealthDataType.steps.readInTimeRange(
startTime: now.subtract(const Duration(days: 1)),
endTime: now,
),
);
for (final StepsRecord record in response.records) {
print('${record.count.value} steps');
}The request fixes the response type to StepsRecord, so no casting is needed.
Aggregate the result
final total = await connector.aggregate(
HealthDataType.steps.aggregateSum(
startTime: now.subtract(const Duration(days: 1)),
endTime: now,
),
);
print('Today: ${total.value} steps');Handle platform failures
Health Connector maps native failures into typed exceptions with stable error codes.
try {
await connector.writeRecords([record]);
} on AuthorizationException catch (error) {
showPermissionHelp(error.message);
} on HealthServiceUnavailableException catch (error) {
disableHealthFeatures(error.code);
} on HealthServiceException catch (error) {
scheduleRetry(error.code);
}Next, review the platform behavior in Permissions and the domain model in Health records.