### Write Workout Routes Permissions and Setup
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Request necessary permissions for workout data and routes, including location services. This is the first step before starting to record workout routes.
```dart
1. Request share/read permissions for both `HealthDataType.WORKOUT` and `HealthDataType.WORKOUT_ROUTE`, and ensure location permissions are granted (iOS: Core Location permissions; Android: `ACCESS_FINE_LOCATION` or `ACCESS_COARSE_LOCATION`).
2. When the workout session starts, open a builder with `final builderId = await health.startWorkoutRoute();`.
```
--------------------------------
### Writing Workout Routes (iOS & Android)
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Guides on how to write workout route data, including requesting permissions, starting a route builder, inserting location data, and finishing or discarding the route.
```APIDOC
## Writing Workout Routes (iOS & Android)
### Description
This section details the process for writing workout route data, which involves requesting specific permissions, managing workout sessions, and handling location data.
### Steps
1. **Request Permissions**: Request share/read permissions for `HealthDataType.WORKOUT` and `HealthDataType.WORKOUT_ROUTE`. Ensure location permissions are granted (iOS: Core Location; Android: `ACCESS_FINE_LOCATION` or `ACCESS_COARSE_LOCATION`).
2. **Start Workout Route**: Initiate a workout route builder using `final builderId = await health.startWorkoutRoute();`.
3. **Collect and Insert GPS Samples**: Use `CLLocationManager` (or equivalent) to collect GPS samples and periodically push ordered batches of `WorkoutRouteLocation` values via `insertWorkoutRouteData`.
4. **Write Workout Data**: Save the workout itself using `writeWorkoutData` and capture the resulting HealthKit workout UUID.
5. **Finish or Discard Route**: Commit the route using `finishWorkoutRoute(builderId: builderId, workoutUuid: workoutUuid, metadata: {...})`, or discard it using `discardWorkoutRoute(builderId)` if the session is cancelled.
### Health Connect Note (Android)
- Android only surfaces routes while the app is in the foreground.
- Other apps' routes may return a `ConsentRequired` flag.
- To read third-party routes, the user must manually grant "Always allow" for "Exercise routes" in Health Connect.
- Declare the following permissions in your Android manifest:
- ``
- ``
- `` (or `ACCESS_COARSE_LOCATION`)
```
--------------------------------
### Full Health Data Flow Example
Source: https://context7.com/carp-dk/carp-health-flutter/llms.txt
This example demonstrates a complete workflow for health data management. It covers initialization, requesting permissions for various data types, writing different kinds of health data (steps, blood pressure, workouts), reading data, deduplicating it, processing the results, and serializing the data points to JSON. It also includes a shortcut for retrieving total steps.
```dart
import 'dart:io';
import 'package:health/health.dart';
final health = Health();
Future fullHealthFlow() async {
// 1. Configure
await health.configure();
// 2. Ensure Health Connect is ready on Android
if (Platform.isAndroid) {
final status = await health.getHealthConnectSdkStatus();
if (status != HealthConnectSdkStatus.sdkAvailable) {
await health.installHealthConnect();
return;
}
}
// 3. Request permissions
final types = [
HealthDataType.STEPS,
HealthDataType.HEART_RATE,
HealthDataType.BLOOD_PRESSURE_SYSTOLIC,
HealthDataType.BLOOD_PRESSURE_DIASTOLIC,
HealthDataType.WORKOUT,
HealthDataType.SLEEP_DEEP,
];
final permissions = List.filled(types.length, HealthDataAccess.READ_WRITE);
await health.requestAuthorization(types, permissions: permissions);
final now = DateTime.now();
final yesterday = now.subtract(const Duration(days: 1));
// 4. Write data
await health.writeHealthData(
value: 8500,
type: HealthDataType.STEPS,
startTime: yesterday,
endTime: now,
);
await health.writeBloodPressure(systolic: 118, diastolic: 76, startTime: now);
await health.writeWorkoutData(
activityType: HealthWorkoutActivityType.HIKING,
start: yesterday.add(const Duration(hours: 9)),
end: yesterday.add(const Duration(hours: 11)),
totalEnergyBurned: 550,
totalDistance: 8200,
);
// 5. Read data
List data = await health.getHealthDataFromTypes(
types: types,
startTime: yesterday,
endTime: now,
recordingMethodsToFilter: [RecordingMethod.unknown],
);
// 6. Deduplicate
data = health.removeDuplicates(data);
// 7. Process results
final stepPoints = data.where((p) => p.type == HealthDataType.STEPS);
int totalSteps = stepPoints.fold(0, (sum, p) {
return sum + (p.value as NumericHealthValue).numericValue.toInt();
});
print('Total steps yesterday: $totalSteps');
// 8. Serialize to JSON for storage
final jsonList = data.map((p) => p.toJson()).toList();
print('Serialized ${jsonList.length} data points to JSON.');
// 9. Get step count shortcut
int? steps = await health.getTotalStepsInInterval(yesterday, now);
print('Aggregate steps: $steps');
}
```
--------------------------------
### getHealthConnectSdkStatus(), isHealthConnectAvailable(), installHealthConnect()
Source: https://context7.com/carp-dk/carp-health-flutter/llms.txt
Android-specific methods to check the runtime availability of Google Health Connect, determine if it's installed, and prompt the user to install or update it.
```APIDOC
## getHealthConnectSdkStatus(), isHealthConnectAvailable(), installHealthConnect()
### Description
Check the runtime availability of Google Health Connect and guide the user to install or update it when needed.
### Method: getHealthConnectSdkStatus
#### Description
Retrieves the current status of the Health Connect SDK.
#### Return Value
* **HealthConnectSdkStatus** - The current status of the Health Connect SDK (e.g., `sdkAvailable`, `sdkUnavailableProviderUpdateRequired`, `sdkUnavailable`).
### Method: isHealthConnectAvailable
#### Description
Checks if Health Connect is available on the device.
#### Return Value
* **boolean** - `true` if Health Connect is available, `false` otherwise.
### Method: installHealthConnect
#### Description
Opens the Google Play Store to prompt the user to install or update Health Connect.
### Example
```dart
Future ensureHealthConnect() async {
if (!Platform.isAndroid) return;
final status = await health.getHealthConnectSdkStatus();
switch (status) {
case HealthConnectSdkStatus.sdkAvailable:
print('Health Connect ready.');
break;
case HealthConnectSdkStatus.sdkUnavailableProviderUpdateRequired:
print('Health Connect needs updating.');
await health.installHealthConnect(); // Opens Play Store
break;
case HealthConnectSdkStatus.sdkUnavailable:
default:
print('Health Connect not installed.');
await health.installHealthConnect(); // Opens Play Store
break;
}
}
```
```
--------------------------------
### Declare Health Connect Queries in AndroidManifest.xml
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Add these queries to your AndroidManifest.xml to check for Health Connect installation and handle permission rationale actions.
```xml
```
--------------------------------
### Getting Total Steps in Interval
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Calculates and returns the total number of steps within a specified time interval. Useful for daily step counts.
```APIDOC
## Getting Total Steps in Interval
### Description
Retrieve the total number of steps recorded within a specified time interval (e.g., from midnight to the current time for today's steps).
### Method
```dart
var now = DateTime.now();
var midnight = DateTime(now.year, now.month, now.day);
// Get total steps for today
int? steps = await health.getTotalStepsInInterval(midnight, now);
```
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Request Example
```dart
var now = DateTime.now();
var midnight = DateTime(now.year, now.month, now.day);
int? steps = await health.getTotalStepsInInterval(midnight, now);
print('Total steps today: $steps');
```
### Response
#### Success Response (int?)
- The total number of steps as an integer, or `null` if data is unavailable.
#### Response Example
```dart
// Example of handling the result
if (steps != null) {
print('Total steps: $steps');
} else {
print('Step count not available.');
}
```
```
--------------------------------
### HealthDataPoint JSON Structure Example
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Illustrates the JSON format for a HealthDataPoint, including nested HealthValue. Note that null values are not serialized and camel_case notation is used.
```json
{
"value": {
"__type": "NumericHealthValue",
"numeric_value": 141.0
},
"type": "STEPS",
"unit": "COUNT",
"date_from": "2024-04-03T10:06:57.736",
"date_to": "2024-04-03T10:12:51.724",
"source_platform": "appleHealth",
"source_device_id": "F74938B9-C011-4DE4-AA5E-CF41B60B96E7",
"source_id": "com.apple.health.81AE7156-EC05-47E3-AC93-2D6F65C717DF",
"source_name": "iPhone12.bardram.net",
"recording_method": 3
"value": {
"__type": "NumericHealthValue",
"numeric_value": 141.0
},
"type": "STEPS",
"unit": "COUNT",
"date_from": "2024-04-03T10:06:57.736",
"date_to": "2024-04-03T10:12:51.724",
"source_platform": "appleHealth",
"source_device_id": "F74938B9-C011-4DE4-AA5E-CF41B60B96E7",
"source_id": "com.apple.health.81AE7156-EC05-47E3-AC93-2D6F65C717DF",
"source_name": "iPhone12.bardram.net",
"recording_method": 2
}
```
--------------------------------
### Get Total Steps in Interval
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Retrieve the total number of steps recorded within a specified time interval, typically from midnight to the current time for daily totals.
```dart
// get the number of steps for today
var midnight = DateTime(now.year, now.month, now.day);
int? steps = await health.getTotalStepsInInterval(midnight, now);
```
--------------------------------
### Ensure Health Connect Availability (Android)
Source: https://context7.com/carp-dk/carp-health-flutter/llms.txt
Checks the runtime availability of Google Health Connect on Android and prompts the user to install or update it if necessary by opening the Play Store.
```dart
Future ensureHealthConnect() async {
if (!Platform.isAndroid) return;
final status = await health.getHealthConnectSdkStatus();
switch (status) {
case HealthConnectSdkStatus.sdkAvailable:
print('Health Connect ready.');
break;
case HealthConnectSdkStatus.sdkUnavailableProviderUpdateRequired:
print('Health Connect needs updating.');
await health.installHealthConnect(); // Opens Play Store
break;
case HealthConnectSdkStatus.sdkUnavailable:
default:
print('Health Connect not installed.');
await health.installHealthConnect(); // Opens Play Store
break;
}
}
```
--------------------------------
### Get Health Connect Changes Token
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/example/README.md
Use this to create a token for incremental synchronization of Health Connect data. The token changes after each call, so you must store and use the `nextChangesToken` for subsequent requests.
```dart
final token = await health.getChangesToken(
types: [HealthDataType.STEPS, HealthDataType.WORKOUT],
);
if (token != null) {
final response = await health.getChanges(changesToken: token);
if (response != null) {
// Apply changes to your local store.
// Upserts replace existing items by uuid; deletions remove by recordId.
for (final change in response.changes) {
if (change.type == HealthChangeType.delete) {
localStore.remove(change.recordId);
continue;
}
final dataPoint = change.dataPoint;
if (dataPoint != null) {
localStore[dataPoint.uuid] = dataPoint;
}
}
// Persist the next token for the next pull.
final nextToken = response.nextChangesToken;
}
}
```
--------------------------------
### Getting Health Data from Types
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Retrieves health data points for specified data types within a given time interval. Requires prior authorization.
```APIDOC
## Getting Health Data from Types
### Description
Fetch health data points for a list of specified data types within a given start and end time. Ensure authorization has been granted for these types.
### Method
```dart
var now = DateTime.now();
// Define the data types to fetch
var types = [
HealthDataType.STEPS,
HealthDataType.BLOOD_GLUCOSE,
];
// Fetch data from the last 24 hours
List healthData = await health.getHealthDataFromTypes(
now.subtract(Duration(days: 1)), now, types);
```
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Request Example
```dart
var now = DateTime.now();
var types = [HealthDataType.STEPS];
List healthData = await health.getHealthDataFromTypes(
now.subtract(Duration(days: 1)), now, types);
```
### Response
#### Success Response (List)
- A list of `HealthDataPoint` objects containing the requested health data.
#### Response Example
```dart
// Example of processing fetched data
for (var dataPoint in healthData) {
print('Value: ${dataPoint.value}, Type: ${dataPoint.dataType}, Date: ${dataPoint.date}');
}
```
```
--------------------------------
### Insert Workout Route Data
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Periodically push batches of `WorkoutRouteLocation` values to the Health plugin after starting a workout route builder. This function is used to record GPS samples.
```dart
3. Collect GPS samples using `CLLocationManager` (or an equivalent service) and periodically push ordered batches of `WorkoutRouteLocation` values via `insertWorkoutRouteData`.
```
--------------------------------
### Health Plugin Initialization and Configuration
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Demonstrates how to initialize the Health plugin and configure it before use. This is a prerequisite for all other operations.
```APIDOC
## Health Plugin Initialization and Configuration
### Description
Initialize the Health plugin and configure it before performing any health data operations. This sets up the connection to the underlying health platform.
### Method
```dart
final health = Health();
await health.configure();
```
```
--------------------------------
### Initialize and Configure Health Plugin
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Instantiate the Health plugin and call the `configure` method before using its functionalities. This is a prerequisite for all other operations.
```dart
// Global Health instance
final health = Health();
// configure the health plugin before use.
await health.configure();
```
--------------------------------
### Configure Android Gradle Properties
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Replace the content of `android/gradle.properties` to enable AndroidX and Jetifier.
```bash
org.gradle.jvmargs=-Xmx1536M
android.enableJetifier=true
android.useAndroidX=true
```
--------------------------------
### Request Activity Recognition Permission
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Include this permission in your AndroidManifest.xml to access fitness data like steps via the Activity Recognition API.
```xml
```
--------------------------------
### Add HealthKit Capabilities to Info.plist
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Add these entries to your Info.plist file to request user permissions for syncing data with Apple Health.
```xml
NSHealthShareUsageDescription
We will sync your data with the Apple Health app to give you better insights
```
```xml
NSHealthUpdateUsageDescription
We will sync your data with the Apple Health app to give you better insights
```
--------------------------------
### Request Permissions using permission_handler plugin
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Use the `permission_handler` plugin in Dart to prompt the user for activity recognition and location permissions, as these are dangerous permissions requiring user action.
```dart
await Permission.activityRecognition.request();
await Permission.location.request();
```
--------------------------------
### Request Read/Write Permissions for Activity Intensity Data
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Declare permissions in AndroidManifest.xml for reading and writing Activity Intensity records from Health Connect.
```xml
```
--------------------------------
### Save Workout and Commit Route
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Save the workout data and capture its UUID, then call `finishWorkoutRoute` to commit the recorded route. If the session is cancelled, use `discardWorkoutRoute`.
```dart
4. Save the workout itself (for example, with `writeWorkoutData`) and capture the resulting HealthKit workout UUID.
5. Call `finishWorkoutRoute(builderId: builderId, workoutUuid: workoutUuid, metadata: {...})` to commit the route, or `discardWorkoutRoute(builderId)` if the session is cancelled.
```
--------------------------------
### HealthDataPoint and JSON serialization
Source: https://context7.com/carp-dk/carp-health-flutter/llms.txt
Details on the `HealthDataPoint` model, including its structure and how to serialize/deserialize it to/from JSON for persistence. Sleep and mindfulness values are converted to duration in minutes.
```APIDOC
## HealthDataPoint and JSON serialization
### Description
Each data point retrieved from the platform is a `HealthDataPoint` with a polymorphic `HealthValue`. Points support `toJson()` / `fromJson()` for persistence. Sleep and mindfulness values are automatically converted to duration in minutes.
### Class: HealthDataPoint
#### Methods
* **toJson()**: Serializes the `HealthDataPoint` to a JSON object.
* **fromJson(Map json)**: Deserializes a JSON object into a `HealthDataPoint`.
#### Fields
* **uuid** (String) - Unique identifier for the data point.
* **value** (`HealthValue`) - The actual health data value (e.g., NumericHealthValue, WorkoutHealthValue).
* **type** (`HealthDataType`) - The type of health data.
* **unit** (`HealthValueUnit`) - The unit of measurement for the data.
* **dateFrom** (DateTime) - The start date/time of the data point.
* **dateTo** (DateTime) - The end date/time of the data point.
* **sourcePlatform** (String) - The platform where the data originated.
* **sourceId** (String) - The ID of the data source.
* **sourceName** (String) - The name of the data source.
* **recordingMethod** (int) - The method used for recording the data.
### Example
```dart
// Reading and serializing data points
final now = DateTime.now();
final points = await health.getHealthDataFromTypes(
types: [HealthDataType.HEART_RATE, HealthDataType.WORKOUT],
startTime: now.subtract(const Duration(hours: 2)),
endTime: now,
);
for (final p in points) {
// Serialize to JSON
final json = p.toJson();
print(json);
// Deserialize back
final restored = HealthDataPoint.fromJson(json);
assert(restored == p);
}
```
```
--------------------------------
### Fetch Health Data with Recording Method Filter
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Fetches health data within a specified time range, with an option to filter by recording methods (e.g., manual entry, automatic). This allows for more granular data retrieval based on how the data was collected.
```APIDOC
## Fetch Health Data with Recording Method Filter
### Description
Fetches health data within a specified time range, with an option to filter by recording methods.
### Method Signature
```dart
Future> getHealthDataFromTypes({
required List types,
required DateTime startTime,
required DateTime endTime,
List? recordingMethodsToFilter,
});
```
### Parameters
#### Path Parameters
- **types** (List) - Required - A list of health data types to fetch.
- **startTime** (DateTime) - Required - The start of the time range for fetching data.
- **endTime** (DateTime) - Required - The end of the time range for fetching data.
- **recordingMethodsToFilter** (List) - Optional - A list of recording methods to filter the results by.
### Request Example
```dart
List healthData = await health.getHealthDataFromTypes(
types: types,
startTime: yesterday,
endTime: now,
recordingMethodsToFilter: [RecordingMethod.manual, RecordingMethod.unknown],
);
```
```
--------------------------------
### getChangesToken({types}) and getChanges({changesToken, includeSelf})
Source: https://context7.com/carp-dk/carp-health-flutter/llms.txt
Android-only API for incremental data synchronization. `getChangesToken` obtains a baseline token, and `getChanges` retrieves data points inserted, updated, or deleted since that token.
```APIDOC
## getChangesToken({types}) and getChanges({changesToken, includeSelf})
### Description
Android-only API for incremental sync. A token marks the current state; subsequent calls to `getChanges` return only the records inserted, updated, or deleted since then.
### Method: getChangesToken
#### Parameters
* **types** (List<`HealthDataType`>) - A list of health data types to track changes for.
#### Return Value
* **String?** - A baseline token representing the current state, or null if an error occurs.
### Method: getChanges
#### Parameters
* **changesToken** (String) - The token obtained from `getChangesToken`.
* **includeSelf** (boolean) - Whether to include records written by this app (default is false).
#### Return Value
* **HealthChangesResponse?** - An object containing changes (upserted data points, deleted record IDs, and next token), or null if an error occurs.
* **changesTokenExpired** (boolean) - True if the token has expired and a re-sync is needed.
* **upsertedDataPoints** (List<`HealthDataPoint`>) - Data points that have been inserted or updated.
* **deletedRecordIds** (List) - IDs of records that have been deleted.
* **hasMore** (boolean) - Indicates if there are more changes available.
* **nextChangesToken** (String) - The token to use for the next poll.
### Example
```dart
// Obtain a baseline token
String? token = await health.getChangesToken(
types: [HealthDataType.STEPS, HealthDataType.WORKOUT]
);
// Poll for changes
if (token != null) {
HealthChangesResponse? response = await health.getChanges(
changesToken: token,
includeSelf: false
);
if (response != null) {
if (response.changesTokenExpired) {
print('Token expired; re-sync from scratch');
} else {
print('Upserted: ${response.upsertedDataPoints.length}');
print('Deleted: ${response.deletedRecordIds.length}');
token = response.nextChangesToken;
}
}
}
```
```
--------------------------------
### Serialize and Deserialize Health Data Points
Source: https://context7.com/carp-dk/carp-health-flutter/llms.txt
Demonstrates reading health data points for specified types and time ranges, serializing them to JSON, and deserializing them back into HealthDataPoint objects. Includes type-checking for different HealthValue types like WorkoutHealthValue and NumericHealthValue.
```dart
// Reading and serializing data points
final now = DateTime.now();
final points = await health.getHealthDataFromTypes(
types: [HealthDataType.HEART_RATE, HealthDataType.WORKOUT],
startTime: now.subtract(const Duration(hours: 2)),
endTime: now,
);
for (final p in points) {
// Serialize to JSON
final json = p.toJson();
print(json);
// Output for a heart rate point:
// {
// "uuid": "A4F2...",
// "value": {"__type": "NumericHealthValue", "numeric_value": 78.0},
// "type": "HEART_RATE",
// "unit": "BEATS_PER_MINUTE",
// "date_from": "2024-04-03T10:06:57.736",
// "date_to": "2024-04-03T10:06:57.736",
// "source_platform": "appleHealth",
// "source_id": "com.apple.Health",
// "source_name": "Health",
// "recording_method": 2
// }
// Deserialize back
final restored = HealthDataPoint.fromJson(json);
assert(restored == p);
// Type-check the value
if (p.value is WorkoutHealthValue) {
final w = p.value as WorkoutHealthValue;
print('Workout: ${w.workoutActivityType.name}, '
'${w.totalDistance}m, ${w.totalEnergyBurned} kcal');
}
if (p.value is NumericHealthValue) {
final n = p.value as NumericHealthValue;
print('${p.type.name}: ${n.numericValue} ${p.unit.name}');
}
}
```
--------------------------------
### Add Intent Filter for Health Connect Permissions Rationale
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Add this intent filter to your MainActivity in AndroidManifest.xml to handle the 'Show Permissions Rationale' action for Health Connect.
```xml
```
--------------------------------
### Manage Background Health Data Permission
Source: https://context7.com/carp-dk/carp-health-flutter/llms.txt
Checks if background health data access is available and requests authorization if not already granted. Requires specific Android manifest permission.
```dart
Future manageBackgroundPermission() async {
if (!Platform.isAndroid) return;
bool available = await health.isHealthDataInBackgroundAvailable();
print('Background data available: $available');
if (available && !(await health.isHealthDataInBackgroundAuthorized())) {
bool granted = await health.requestHealthDataInBackgroundAuthorization();
print('Background access granted: $granted');
// Output: Background access granted: true
}
}
```
--------------------------------
### Request Read/Write Permissions and Write Health Data
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Request explicit read and write permissions for health data types and then write new data points. Note that the `recordingMethod` parameter has platform-specific support.
```dart
// request permissions to write steps and blood glucose
types = [HealthDataType.STEPS, HealthDataType.BLOOD_GLUCOSE];
var permissions = [
HealthDataAccess.READ_WRITE,
HealthDataAccess.READ_WRITE
];
await health.requestAuthorization(types, permissions: permissions);
// write steps and blood glucose
bool success = await health.writeHealthData(10, HealthDataType.STEPS, now, now);
success = await health.writeHealthData(3.1, HealthDataType.BLOOD_GLUCOSE, now, now);
// you can also specify the recording method to store in the metadata (default is RecordingMethod.automatic)
// on iOS only `RecordingMethod.automatic` and `RecordingMethod.manual` are supported
// Android additionally supports `RecordingMethod.active` and `RecordingMethod.unknown`
success &= await health.writeHealthData(10, HealthDataType.STEPS, now, now, recordingMethod: RecordingMethod.manual);
```
--------------------------------
### Filter Health Data by Recording Method
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Fetches health data, optionally filtering by recording methods like manual or unknown. Note that data must have been written with this metadata for filtering to be effective.
```dart
List healthData = await health.getHealthDataFromTypes(
types: types,
startTime: yesterday,
endTime: now,
recordingMethodsToFilter: [RecordingMethod.manual, RecordingMethod.unknown],
);
```
--------------------------------
### Configure Activity Alias for Health Connect Permissions
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Define an activity-alias in AndroidManifest.xml to link to your privacy policy from the Health Connect permissions activity. Ensure the target activity displays your privacy policy.
```xml
```
--------------------------------
### Request Read/Write Permissions for Heart Rate Data
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Declare the necessary permissions in AndroidManifest.xml to read and write heart rate data via Health Connect.
```xml
```
--------------------------------
### Android Health Connect Permissions for Workout Routes
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Declare necessary permissions in the Android manifest for reading and writing exercise routes and accessing location data. Note that Health Connect has specific limitations regarding route visibility and access.
```xml
- ``
- ``
- `` (or `ACCESS_COARSE_LOCATION`)
```
--------------------------------
### Requesting Health Data Authorization
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Shows how to request user permission to access specific types of health data. Authorization must be granted before reading data.
```APIDOC
## Requesting Health Data Authorization
### Description
Request authorization from the user to access specific health data types. This is a necessary step before reading or writing data.
### Method
```dart
// Define the data types for which to request access
var types = [
HealthDataType.STEPS,
HealthDataType.BLOOD_GLUCOSE,
];
// Request authorization
bool requested = await health.requestAuthorization(types);
```
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Request Example
```dart
var types = [
HealthDataType.STEPS,
HealthDataType.BLOOD_GLUCOSE,
];
await health.requestAuthorization(types);
```
### Response
#### Success Response (bool)
- `true` if authorization was granted, `false` otherwise.
#### Response Example
```dart
// Example of checking the authorization status
if (requested) {
print('Authorization granted');
} else {
print('Authorization denied');
}
```
```
--------------------------------
### Track Health Connect Changes (Android)
Source: https://context7.com/carp-dk/carp-health-flutter/llms.txt
Uses Android-only Health Connect APIs to obtain a changes token and retrieve incremental data updates (upserted and deleted records). Store the token persistently and handle token expiration by re-fetching the baseline token.
```dart
Future trackChanges() async {
// 1. Obtain a baseline token (store this persistently)
String? token = await health.getChangesToken(
types: [HealthDataType.STEPS, HealthDataType.WORKOUT],
);
print('Token: $token');
// Output: Token: ChAIARIGCAES...
// --- Later, to poll for changes ---
if (token == null) return;
HealthChangesResponse? response = await health.getChanges(
changesToken: token,
includeSelf: false, // exclude records written by this app
);
if (response == null) return;
if (response.changesTokenExpired) {
print('Token expired; re-fetch baseline token and re-sync from scratch');
return;
}
print('Upserted: ${response.upsertedDataPoints.length}');
print('Deleted: ${response.deletedRecordIds.length}');
print('Has more: ${response.hasMore}');
// Output:
// Upserted: 3
// Deleted: 1
// Has more: false
for (final point in response.upsertedDataPoints) {
print('New/updated: ${point.type.name} @ ${point.dateFrom}');
}
// Advance the token for the next poll
token = response.nextChangesToken;
}
```
--------------------------------
### isDataTypeAvailable(dataType)
Source: https://context7.com/carp-dk/carp-health-flutter/llms.txt
Checks if a specific HealthDataType is supported on the current platform (iOS or Android). Returns true if supported, false otherwise.
```APIDOC
## isDataTypeAvailable(dataType)
### Description
Returns `true` if the given `HealthDataType` is supported on the current platform (iOS or Android).
### Method Signature
`isDataTypeAvailable(HealthDataType dataType)`
### Parameters
* **dataType** (`HealthDataType`) - The health data type to check for availability.
### Return Value
* **boolean** - `true` if the data type is available, `false` otherwise.
### Example
```dart
print(health.isDataTypeAvailable(HealthDataType.ELECTROCARDIOGRAM));
// iOS output: true
// Android output: false
```
```
--------------------------------
### writeActivityIntensity
Source: https://context7.com/carp-dk/carp-health-flutter/llms.txt
Writes an `ActivityIntensityRecord` to Google Health Connect (Android only). Uses `ActivityIntensityLevel.moderate` or `ActivityIntensityLevel.vigorous`.
```APIDOC
## writeActivityIntensity({intensityLevel, startTime, endTime, recordingMethod})
### Description
Writes an `ActivityIntensityRecord` to Google Health Connect (Android only). Uses `ActivityIntensityLevel.moderate` or `ActivityIntensityLevel.vigorous`.
### Parameters
- **intensityLevel** (ActivityIntensityLevel) - Required - The level of activity intensity (moderate or vigorous).
- **startTime** (DateTime) - Required - The start time of the activity.
- **endTime** (DateTime) - Required - The end time of the activity.
- **recordingMethod** (RecordingMethod) - Optional - The method used for recording the data.
```
--------------------------------
### Add Android Background Health Data Permission
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Add this permission to your AndroidManifest.XML to allow apps to read health data in the background. Ensure this is declared within the manifest tag.
```XML
```
--------------------------------
### Fetch Health Data by UUID
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Retrieve a single health data record using its unique identifier (UUID) and data type.
```APIDOC
## Fetch Health Data by UUID
### Description
Retrieves a specific health data point using its UUID and HealthDataType.
### Method Signature
`Future getHealthDataByUUID({required String uuid, required HealthDataType type})`
### Parameters
#### Path Parameters
- **uuid** (String) - Required - The unique identifier of the health data record.
- **type** (HealthDataType) - Required - The type of health data to retrieve (e.g., HealthDataType.WORKOUT).
### Request Example
```dart
HealthDataPoint? healthPoint = await health.getHealthDataByUUID(
uuid: 'E9F2EEAD-8FC5-4CE5-9FF5-7C4E535FB8B8',
type: HealthDataType.WORKOUT,
);
```
### Response
#### Success Response
- **HealthDataPoint?**: An object containing the health data if found, otherwise null.
- **uuid** (String)
- **value** (dynamic)
- **unit** (String)
- **dateFrom** (DateTime)
- **dateTo** (DateTime)
- **dataType** (HealthDataType)
- **platform** (HealthPlatformType)
- **deviceId** (String)
- **sourceId** (String)
- **sourceName** (String)
- **recordingMethod** (RecordingMethod)
- **workoutSummary** (WorkoutSummary)
- **metadata** (dynamic)
- **deviceModel** (dynamic)
### Response Example
```json
{
"uuid": "E9F2EEAD-8FC5-4CE5-9FF5-7C4E535FB8B8",
"value": {
"workoutActivityType": "RUNNING",
"totalEnergyBurned": null,
"totalEnergyBurnedUnit": "KILOCALORIE",
"totalDistance": 2400,
"totalDistanceUnit": "METER",
"totalSteps": null,
"totalStepsUnit": null
},
"unit": "NO_UNIT",
"dateFrom": "2025-05-02T07:31:00.000",
"dateTo": "2025-05-02T08:25:00.000",
"dataType": "WORKOUT",
"platform": "HealthPlatformType.appleHealth",
"deviceId": "unknown",
"sourceId": "com.apple.Health",
"sourceName": "Health",
"recordingMethod": "RecordingMethod.manual",
"workoutSummary": {
"workoutType": "running",
"totalDistance": 2400,
"totalEnergyBurned": 0,
"totalSteps": 0
},
"metadata": null,
"deviceModel": null
}
```
```
--------------------------------
### Manage Health Data History Permission
Source: https://context7.com/carp-dk/carp-health-flutter/llms.txt
Checks if historical data access is available and requests authorization if not already granted. This is restricted to Android devices.
```dart
Future manageHistoryPermission() async {
if (!Platform.isAndroid) return;
bool available = await health.isHealthDataHistoryAvailable();
if (!available) {
print('Historical data access not supported on this device.');
return;
}
bool authorized = await health.isHealthDataHistoryAuthorized();
if (!authorized) {
authorized = await health.requestHealthDataHistoryAuthorization();
print('History authorization granted: $authorized');
// Output: History authorization granted: true
}
}
```
--------------------------------
### Request Authorization and Read Health Data
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Request authorization for specific health data types and then retrieve data within a specified time interval. Ensure permissions are requested before attempting to read data.
```dart
// define the types to get
var types = [
HealthDataType.STEPS,
HealthDataType.BLOOD_GLUCOSE,
];
// requesting access to the data types before reading them
bool requested = await health.requestAuthorization(types);
var now = DateTime.now();
// fetch health data from the last 24 hours
List healthData = await health.getHealthDataFromTypes(
now.subtract(Duration(days: 1)), now, types);
```
--------------------------------
### Fetch Single Health Data by UUID
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Retrieves a single health data point by its unique identifier (UUID) and data type. This is useful when you have a specific record's UUID stored, perhaps from a database.
```APIDOC
## Fetch Single Health Data by UUID
### Description
Retrieves a single health data point by its unique identifier (UUID) and data type.
### Method Signature
```dart
Future getHealthDataByUUID({
required String uuid,
required HealthDataType type,
});
```
### Parameters
#### Path Parameters
- **uuid** (String) - Required - The unique identifier of the health data point.
- **type** (HealthDataType) - Required - The type of health data to retrieve (e.g., HealthDataType.STEPS).
### Request Example
```dart
HealthDataPoint? healthPoint = await health.getHealthDataByUUID(
uuid: 'random-uuid-string',
type: HealthDataType.STEPS,
);
```
### Response Example
```json
{
"uuid": "random-uuid-string",
"value": "12",
"date_from": 1742259061009,
"date_to": 1742259092888,
"source_id": "com.google.android.apps.fitness",
"source_name": "com.google.android.apps.fitness",
"recording_method": 0
}
```
```
--------------------------------
### Extend FlutterFragmentActivity for Android 14 Compatibility
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
For Android 14, update your MainActivity to extend `FlutterFragmentActivity` instead of `FlutterActivity` to support `registerForActivityResult` for Health Connect permissions.
```kotlin
import io.flutter.embedding.android.FlutterFragmentActivity
...
class MainActivity: FlutterFragmentActivity() {
...}
```
--------------------------------
### Request Location Permissions for Workout Distance
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Declare these permissions in AndroidManifest.xml if your app needs to access workout distances, which requires location data.
```xml
```
--------------------------------
### Background Health Data Access
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Functions to check availability and request authorization for reading health data in the background.
```APIDOC
## Background Health Data Access
### Description
Provides functions to manage background health data reading capabilities.
### Functions
- `isHealthDataInBackgroundAvailable()`: Checks if the Health Data in Background feature is available on the device.
- `isHealthDataInBackgroundAuthorized()`: Checks the current authorization status for reading health data in the background.
- `requestHealthDataInBackgroundAuthorization()`: Requests the user to grant permission for reading health data in the background.
```
--------------------------------
### Fetch Single Health Data Record by UUID
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Retrieve a specific health data record by providing its unique identifier (UUID) and data type. This function is useful for accessing individual records stored in your database.
```Dart
HealthDataPoint? healthPoint = await health.getHealthDataByUUID(
uuid: 'E9F2EEAD-8FC5-4CE5-9FF5-7C4E535FB8B8',
type: HealthDataType.WORKOUT,
);
```
--------------------------------
### Manage Background Health Data Access
Source: https://context7.com/carp-dk/carp-health-flutter/llms.txt
Manages the permission to read Health Connect data while the app is in the background on Android. Requires specific manifest permission.
```APIDOC
## `isHealthDataInBackgroundAvailable()`, `isHealthDataInBackgroundAuthorized()`, `requestHealthDataInBackgroundAuthorization()`
### Description
Manage the permission to read Health Connect data while the app is in the background. This feature requires the `android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND` permission to be declared in `AndroidManifest.xml` and is specific to Android.
### Methods
- `isHealthDataInBackgroundAvailable()`: Checks if background data access is supported on the device.
- `isHealthDataInBackgroundAuthorized()`: Checks if the app is currently authorized for background data access.
- `requestHealthDataInBackgroundAuthorization()`: Requests authorization from the user for background data access.
### Usage Example
```dart
Future manageBackgroundPermission() async {
if (!Platform.isAndroid) return;
bool available = await health.isHealthDataInBackgroundAvailable();
print('Background data available: $available');
if (available && !(await health.isHealthDataInBackgroundAuthorized())) {
bool granted = await health.requestHealthDataInBackgroundAuthorization();
print('Background access granted: $granted');
}
}
```
```
--------------------------------
### Manage Health Data History Permission
Source: https://context7.com/carp-dk/carp-health-flutter/llms.txt
Manages the special permission required to read historical health data beyond the default 30-day window in Health Connect. This is relevant for Android devices.
```APIDOC
## `isHealthDataHistoryAvailable()`, `isHealthDataHistoryAuthorized()`, `requestHealthDataHistoryAuthorization()`
### Description
These methods manage the special permission for reading historical health data beyond the default 30-day window in Health Connect. This functionality is specific to Android.
### Methods
- `isHealthDataHistoryAvailable()`: Checks if historical data access is supported on the device.
- `isHealthDataHistoryAuthorized()`: Checks if the app is currently authorized to read historical health data.
- `requestHealthDataHistoryAuthorization()`: Requests authorization from the user to read historical health data.
### Usage Example
```dart
Future manageHistoryPermission() async {
if (!Platform.isAndroid) return;
bool available = await health.isHealthDataHistoryAvailable();
if (!available) {
print('Historical data access not supported on this device.');
return;
}
bool authorized = await health.isHealthDataHistoryAuthorized();
if (!authorized) {
authorized = await health.requestHealthDataHistoryAuthorization();
print('History authorization granted: $authorized');
}
}
```
```
--------------------------------
### Fetch Single Health Data by UUID
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Retrieves a single health data point using its UUID and HealthDataType. Ensure the device is unlocked on iOS before making requests.
```dart
HealthDataPoint? healthPoint = await health.getHealthDataByUUID(
uuid: 'random-uuid-string',
type: HealthDataType.STEPS,
);
```
--------------------------------
### Check Health Data Type Availability
Source: https://context7.com/carp-dk/carp-health-flutter/llms.txt
Verifies if a specific HealthDataType is supported on the current platform (iOS or Android).
```dart
void checkAvailability() {
print(health.isDataTypeAvailable(HealthDataType.ELECTROCARDIOGRAM));
// iOS output: true
// Android output: false
print(health.isDataTypeAvailable(HealthDataType.ACTIVITY_INTENSITY));
// iOS output: false
// Android output: true
}
```
--------------------------------
### Remove Duplicate Health Data Points
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Demonstrates how to remove duplicate HealthDataPoint objects from a list. Individual data points can be compared using the == operator.
```dart
List points = ...;
points = health.removeDuplicates(points);
```
--------------------------------
### Writing Health Data
Source: https://github.com/carp-dk/carp-health-flutter/blob/main/README.md
Writes health data points for specified data types. This operation requires appropriate read/write permissions.
```APIDOC
## Writing Health Data
### Description
Write health data points, such as steps or blood glucose, to the health platform. This requires prior authorization with read and write permissions.
### Method
```dart
var now = DateTime.now();
// Write steps data
bool successSteps = await health.writeHealthData(10, HealthDataType.STEPS, now, now);
// Write blood glucose data
bool successGlucose = await health.writeHealthData(3.1, HealthDataType.BLOOD_GLUCOSE, now, now);
// Write steps with a specific recording method
success &= await health.writeHealthData(10, HealthDataType.STEPS, now, now, recordingMethod: RecordingMethod.manual);
```
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Request Example
```dart
var now = DateTime.now();
await health.writeHealthData(5000, HealthDataType.STEPS, now, now);
```
### Response
#### Success Response (bool)
- `true` if the data was written successfully, `false` otherwise.
#### Response Example
```dart
// Example of checking write success
if (successSteps) {
print('Steps data written successfully');
}
```
```