health
v13.3.1Wrapper for Apple's HealthKit on iOS and Google's Health Connect on Android.
Архив пакета: https://pubdev.letsnova.ru/api/archives/health/13.3.1.tar.gz
dart pub add healthREADME
Health
Enables reading and writing health data from/to Apple Health and Google Health Connect.
NOTE: Google has deprecated the Google Fit API. According to the documentation, as of May 1st 2024 developers cannot sign up for using the API. As such, this package has removed support for Google Fit as of version 11.0.0 and users are urged to upgrade as soon as possible.
The plugin supports:
- handling permissions to access health data using the
hasPermissions,requestAuthorization,revokePermissionsmethods. - reading health data using the
getHealthDataFromTypesmethod. - writing health data using the
writeHealthDatamethod. - writing workouts using the
writeWorkoutmethod. - writing workout routes on iOS and Android using the
startWorkoutRoute/insertWorkoutRouteData/finishWorkoutRoutemethods. - writing meals on iOS (Apple Health) & Android using the
writeMealmethod. - writing audiograms on iOS using the
writeAudiogrammethod. - writing blood pressure data using the
writeBloodPressuremethod. - accessing total step counts using the
getTotalStepsInIntervalmethod. - cleaning up duplicate data points via the
removeDuplicatesmethod. - removing data of a given type in a selected period of time using the
deletemethod.
Note that for Android, the target phone needs to have the Health Connect app installed (which is currently in beta) and have access to the internet.
See the tables below for supported health and workout data types.
Setup
Apple Health (iOS)
First, add the following 2 entries to the Info.plist:
<key>NSHealthShareUsageDescription</key>
<string>We will sync your data with the Apple Health app to give you better insights</string>
<key>NSHealthUpdateUsageDescription</key>
<string>We will sync your data with the Apple Health app to give you better insights</string>
Then, open your Flutter project in Xcode by right clicking on the "ios" folder and selecting "Open in Xcode". Next, enable "HealthKit" by adding a capability inside the "Signing & Capabilities" tab of the Runner target's settings.
Google Health Connect (Android)
Health Connect requires the following lines in the AndroidManifest.xml file (see also the example app):
<!-- Check whether Health Connect is installed or not -->
<queries>
<package android:name="com.google.android.apps.healthdata" />
<intent>
<action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
</intent>
</queries>
In the Health Connect permissions activity there is a link to your privacy policy. You need to grant the Health Connect app access in order to link back to your privacy policy. In the example below, you should either replace .MainActivity with an activity that presents the privacy policy or have the Main Activity route the user to the policy. This step may be required to pass Google app review when requesting access to sensitive permissions.
<activity-alias
android:name="ViewPermissionUsageActivity"
android:exported="true"
android:targetActivity=".MainActivity"
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>
For each data type you want to access, the READ and WRITE permissions need to be added to the AndroidManifest.xml file. The list of permissions can be found here on the data types page.
An example of asking for permission to read and write heart rate data is shown below and more examples can also be found in the example app.
<uses-permission android:name="android.permission.health.READ_HEART_RATE"/>
<uses-permission android:name="android.permission.health.WRITE_HEART_RATE"/>
If you plan to read or write Activity Intensity records (the HealthDataType.ACTIVITY_INTENSITY type), be sure to add the corresponding Health Connect permissions introduced with that data type:
<uses-permission android:name="android.permission.health.READ_ACTIVITY_INTENSITY"/>
<uses-permission android:name="android.permission.health.WRITE_ACTIVITY_INTENSITY"/>
By default, Health Connect restricts read data to 30 days from when permission has been granted.
You can check and request access to historical data using the isHealthDataHistoryAuthorized and requestHealthDataHistoryAuthorization methods, respectively.
The above methods require the following permission to be declared:
<uses-permission android:name="android.permission.health.READ_HEALTH_DATA_HISTORY"/>
Accessing fitness data (e.g. Steps) requires permission to access the "Activity Recognition" API. To set it add the following line to your AndroidManifest.xml file.
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
Additionally, for workouts, if the distance of a workout is requested then the location permissions below are needed.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Because this is labeled as a dangerous protection level, the permission system will not grant it automatically and it requires the user's action.
You can prompt the user for it using the permission_handler plugin.
Follow the plugin setup instructions and add the following line before requesting the data:
await Permission.activityRecognition.request();
await Permission.location.request();
Finally, an intent-filter needs to be added to the .MainActivity activity.
<activity
android:name=".MainActivity"
android:exported="true"
....
<!-- Intention to show Permissions screen for Health Connect API -->
<intent-filter>
<action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
</intent-filter>
</activity>
There's a debug, main and profile version which are chosen depending on how you start your app. In general, it's sufficient to add permission only to the main version.
Android 14
This plugin uses the new registerForActivityResult when requesting permissions from Health Connect.
In order for that to work, the Main app's activity should extend FlutterFragmentActivity instead of FlutterActivity.
This adjustment allows casting from Activity to ComponentActivity for accessing registerForActivityResult.
In your MainActivity.kt file, update the MainActivity class so that it extends FlutterFragmentActivity instead of the default FlutterActivity:
...
import io.flutter.embedding.android.FlutterFragmentActivity
...
class MainActivity: FlutterFragmentActivity() {
...
}
Android X
Replace the content of the android/gradle.properties file with the following lines:
org.gradle.jvmargs=-Xmx1536M
android.enableJetifier=true
android.useAndroidX=true
Usage
See the example app for detailed examples of how to use the Health API.
A instance of the Health plugin is create using the Health() constructor and is subsequently configured calling the configure method. Once configured, the plugin can be used for handling permissions and getting and adding data to Apple Health or Google Health Connect.
Below is a simplified flow of how to use the plugin.
// Global Health instance
final health = Health();
// configure the health plugin before use.
await health.configure();
// 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<HealthDataPoint> healthData = await health.getHealthDataFromTypes(
now.subtract(Duration(days: 1)), now, types);
// 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);
// get the number of steps for today
var midnight = DateTime(now.year, now.month, now.day);
int? steps = await health.getTotalStepsInInterval(midnight, now);
Writing workout routes (iOS & Android)
- Request share/read permissions for both
HealthDataType.WORKOUTandHealthDataType.WORKOUT_ROUTE, and ensure location permissions are granted (iOS: Core Location permissions; Android:ACCESS_FINE_LOCATIONorACCESS_COARSE_LOCATION). - When the workout session starts, open a builder with
final builderId = await health.startWorkoutRoute();. - Collect GPS samples using
CLLocationManager(or an equivalent service) and periodically push ordered batches ofWorkoutRouteLocationvalues viainsertWorkoutRouteData. - Save the workout itself (for example, with
writeWorkoutData) and capture the resulting HealthKit workout UUID. - Call
finishWorkoutRoute(builderId: builderId, workoutUuid: workoutUuid, metadata: {...})to commit the route, ordiscardWorkoutRoute(builderId)if the session is cancelled.
Health Connect note: Android only surfaces routes while your app is in the foreground, and other apps' routes may return a
ConsentRequiredflag. Today (Health Connect 1.1.0) the system does not expose theExerciseRouteRequestContractdocumented by Google, so the only way to read third-party routes is to have the user manually grant "Always allow" for Exercise routes inside the Health Connect app (Health Connect → App permissions → Your app → Exercise routes). Also remember to declare the following permissions in your Android manifest:
<uses-permission android:name="android.permission.health.READ_EXERCISE_ROUTE"/><uses-permission android:name="android.permission.health.WRITE_EXERCISE_ROUTE"/><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>(orACCESS_COARSE_LOCATION)
Health Data
A HealthDataPoint object contains the following data fields:
String uuid;
HealthValue value;
HealthDataType type;
HealthDataUnit unit;
DateTime dateFrom;
DateTime dateTo;
HealthPlatformType sourcePlatform;
String sourceDeviceId;
String sourceId;
String sourceName;
RecordingMethod recordingMethod;
WorkoutSummary? workoutSummary;
where a HealthValue can be any type of AudiogramHealthValue, ElectrocardiogramHealthValue, ElectrocardiogramVoltageValue, NumericHealthValue, NutritionHealthValue, or WorkoutHealthValue.
A HealthDataPoint object can be serialized to and from JSON using the toJson() and fromJson() methods. JSON serialization is using camel_case notation. Null values are not serialized. For example;
{
"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
}
Fetch health data
See the example app for a showcasing of how it's done.
Note On iOS the device must be unlocked before health data can be requested. Otherwise an error will be thrown:
flutter: Health Plugin Error:
flutter: PlatformException(FlutterHealth, Results are null, Optional(Error Domain=com.apple.healthkit Code=6 "Protected health data is inaccessible" UserInfo={NSLocalizedDescription=Protected health data is inaccessible}))
Fetch single health data by UUID
In order to retrieve a single record, it is required to provide String uuid and HealthDataType type.
Please see example below:
HealthDataPoint? healthPoint = await health.getHealthDataByUUID(
uuid: 'random-uuid-string',
type: HealthDataType.STEPS,
);
I/FLUTTER_HEALTH( 9161): Success: {uuid=random-uuid-string, value=12, date_from=1742259061009, date_to=1742259092888, source_id=, source_name=com.google.android.apps.fitness, recording_method=0}
Assuming that the
uuidandtypeare coming from your database.
Filtering by recording method
Google Health Connect and Apple HealthKit both provide ways to distinguish samples collected "automatically" and manually entered data by the user.
- Android provides an enum with 4 variations: https://developer.android.com/reference/kotlin/androidx/health/connect/client/records/metadata/Metadata#summary
- iOS has a boolean value: https://developer.apple.com/documentation/healthkit/hkmetadatakeywasuserentered
As such, when fetching data you have the option to filter the fetched data by recording method as such:
List<HealthDataPoint> healthData = await health.getHealthDataFromTypes(
types: types,
startTime: yesterday,
endTime: now,
recordingMethodsToFilter: [RecordingMethod.manual, RecordingMethod.unknown],
);
Note that for this to work, the information needs to have been provided when writing the data to Health Connect or Apple Health. For example, steps added manually through the Apple Health App will set HKWasUserEntered to true (corresponding to RecordingMethod.manual), however it seems that adding steps manually to Google Fit does not write the data with the RecordingMethod.manual in the metadata, instead it shows up as RecordingMethod.unknown. This is an open issue, and as such filtering manual entries when querying step count on Android with getTotalStepsInInterval(includeManualEntries: false) does not necessarily filter out manual steps.
NOTE: On iOS, you can only filter by RecordingMethod.automatic and RecordingMethod.manual as it is stored HKMetadataKeyWasUserEntered is a boolean value in the metadata.
Filtering out duplicates
If the same data is requested multiple times and saved in the same array duplicates will occur.
A single data point can be compared to each other with the == operator, i.e.
HealthDataPoint p1 = ...;
HealthDataPoint p2 = ...;
bool same = p1 == p2;
If you have a list of data points, duplicates can be removed with:
List<HealthDataPoint> points = ...;
points = health.removeDuplicates(points);
Android: Reading Health Data in Background
Currently health connect allows apps to read health data in the background. In order to achieve this add the following permission to your AndroidManifest.XML:
<!-- For reading data in background -->
<uses-permission android:name="android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND"/>
Furthermore, the plugin now exposes three new functions to help you check and request access to read data in the background:
isHealthDataInBackgroundAvailable(): Checks if the Health Data in Background feature is availableisHealthDataInBackgroundAuthorized(): Checks the current status of the Health Data in Background permissionrequestHealthDataInBackgroundAuthorization(): Requests the Health Data in Background permission.
Fetch single health data by UUID
In order to retrieve a single record, it is required to provide String uuid and HealthDataType type.
Please see example below:
HealthDataPoint? healthPoint = await health.getHealthDataByUUID(
uuid: 'E9F2EEAD-8FC5-4CE5-9FF5-7C4E535FB8B8',
type: HealthDataType.WORKOUT,
);
data by UUID: HealthDataPoint -
uuid: E9F2EEAD-8FC5-4CE5-9FF5-7C4E535FB8B8,
value: WorkoutHealthValue - workoutActivityType: RUNNING,
totalEnergyBurned: null,
totalEnergyBurnedUnit: KILOCALORIE,
totalDistance: 2400,
totalDistanceUnit: METER
totalSteps: null,
totalStepsUnit: null,
unit: NO_UNIT,
dateFrom: 2025-05-02 07:31:00.000,
dateTo: 2025-05-02 08:25:00.000,
dataType: WORKOUT,
platform: HealthPlatformType.appleHealth,
deviceId: unknown,
sourceId: com.apple.Health,
sourceName: Health
recordingMethod: RecordingMethod.manual
workoutSummary: WorkoutSummary - workoutType: runningtotalDistance: 2400, totalEnergyBurned: 0, totalSteps: 0
metadata: null
deviceModel: null
Assuming that the
uuidandtypeare coming from your database.
Data Types
The plugin supports the following HealthDataType.
| Data Type | Unit | Apple Health | Google Health Connect | Comments |
|---|---|---|---|---|
| ACTIVE_ENERGY_BURNED | CALORIES | yes | yes | |
| ATRIAL_FIBRILLATION_BURDEN | PERCENTAGE | yes | ||
| BASAL_ENERGY_BURNED | CALORIES | yes | yes | |
| BLOOD_GLUCOSE | MILLIGRAM_PER_DECILITER | yes | yes | |
| BLOOD_OXYGEN | PERCENTAGE | yes | yes | |
| BLOOD_PRESSURE_DIASTOLIC | MILLIMETER_OF_MERCURY | yes | yes | |
| BLOOD_PRESSURE_SYSTOLIC | MILLIMETER_OF_MERCURY | yes | yes | |
| BODY_FAT_PERCENTAGE | PERCENTAGE | yes | yes | |
| BODY_MASS_INDEX | NO_UNIT | yes | yes | |
| BODY_TEMPERATURE | DEGREE_CELSIUS | yes | yes | |
| BODY_WATER_MASS | KILOGRAMS | yes | ||
| ELECTRODERMAL_ACTIVITY | SIEMENS | yes | ||
| HEART_RATE | BEATS_PER_MINUTE | yes | yes | |
| HEIGHT | METERS | yes | yes | |
| RESTING_HEART_RATE | BEATS_PER_MINUTE | yes | yes | |
| RESPIRATORY_RATE | RESPIRATIONS_PER_MINUTE | yes | yes | |
| PERIPHERAL_PERFUSION_INDEX | PERCENTAGE | yes | ||
| STEPS | COUNT | yes | yes | |
| WAIST_CIRCUMFERENCE | METERS | yes | ||
| WALKING_HEART_RATE | BEATS_PER_MINUTE | yes | ||
| WEIGHT | KILOGRAMS | yes | yes | |
| DISTANCE_WALKING_RUNNING | METERS | yes | ||
| FLIGHTS_CLIMBED | COUNT | yes | yes | |
| DISTANCE_DELTA | METERS | yes | ||
| MINDFULNESS | MINUTES | yes | ||
| SLEEP_ASLEEP | MINUTES | yes | yes | on iOS, this refers to asleepUnspecified, and on Android this refers to STAGE_TYPE_SLEEPING (asleep but specific stage is unknown) |
| SLEEP_AWAKE | MINUTES | yes | yes | |
| SLEEP_AWAKE_IN_BED | MINUTES | yes | ||
| SLEEP_DEEP | MINUTES | yes | yes | |
| SLEEP_IN_BED | MINUTES | yes | ||
| SLEEP_LIGHT | MINUTES | yes | yes | on iOS, this refers to asleepCore |
| SLEEP_OUT_OF_BED | MINUTES | yes | ||
| SLEEP_REM | MINUTES | yes | yes | |
| SLEEP_UNKNOWN | MINUTES | yes | ||
| SLEEP_SESSION | MINUTES | yes | ||
| WATER | LITER | yes | yes | |
| EXERCISE_TIME | MINUTES | yes | ||
| WORKOUT | NO_UNIT | yes | yes | See table below |
| WORKOUT_ROUTE | NO_UNIT | yes | yes | iOS 11+ and Android (as Exercise Route); use the workout route builder APIs described in the Writing workout routes section above. |
| HIGH_HEART_RATE_EVENT | NO_UNIT | yes | Requires Apple Watch to write the data | |
| LOW_HEART_RATE_EVENT | NO_UNIT | yes | Requires Apple Watch to write the data | |
| IRREGULAR_HEART_RATE_EVENT | NO_UNIT | yes | Requires Apple Watch to write the data | |
| HEART_RATE_VARIABILITY_RMSSD | MILLISECONDS | yes | ||
| HEART_RATE_VARIABILITY_SDNN | MILLISECONDS | yes | Requires Apple Watch to write the data | |
| HEADACHE_NOT_PRESENT | MINUTES | yes | ||
| HEADACHE_MILD | MINUTES | yes | ||
| HEADACHE_MODERATE | MINUTES | yes | ||
| HEADACHE_SEVERE | MINUTES | yes | ||
| HEADACHE_UNSPECIFIED | MINUTES | yes | ||
| AUDIOGRAM | DECIBEL_HEARING_LEVEL | yes | ||
| ELECTROCARDIOGRAM | VOLT | yes | Requires Apple Watch to write the data | |
| NUTRITION | NO_UNIT | yes | yes | |
| INSULIN_DELIVERY | INTERNATIONAL_UNIT | yes | ||
| MENSTRUATION_FLOW | NO_UNIT | yes | yes | |
| WATER_TEMPERATURE | DEGREE_CELSIUS | yes | Related to/Requires Apple Watch Ultra's Underwater Diving Workout | |
| SLEEP_WRIST_TEMPERATURE | DEGREE_CELSIUS | yes | READ Only - appleSleepingWristTemperature |
|
| SKIN_TEMPERATURE | DEGREE_CELSIUS | yes | Must check health connect for availability | |
| UNDERWATER_DEPTH | METER | yes | Related to/Requires Apple Watch Ultra's Underwater Diving Workout | |
| UV_INDEX | COUNT | yes | ||
| LEAN_BODY_MASS | KILOGRAMS | yes | yes | |
| WALKING_SPEED | METER_PER_SECOND | yes | (yes) | On Android this will be recorded as SPEED with similar unit |
| APPLE_MOVE_TIME | SECOND | yes | READ Only | |
| APPLE_STAND_HOUR | HOUR | yes | READ Only | |
| APPLE_MOVE_TIME | SECOND | yes | READ Only |
Workout Types
The plugin supports the following HealthWorkoutActivityType.
| Workout Type | Apple Health | Google Health Connect | Comments |
|---|---|---|---|
| AMERICAN_FOOTBALL | yes | yes | |
| ARCHERY | yes | ||
| AUSTRALIAN_FOOTBALL | yes | yes | |
| BADMINTON | yes | yes | |
| BARRE | yes | ||
| BASEBALL | yes | yes | |
| BASKETBALL | yes | yes | |
| BIKING | yes | yes | on iOS this is CYCLING, but name changed here to fit with Android |
| BOWLING | yes | ||
| BOXING | yes | yes | |
| CALISTHENICS | yes | ||
| CARDIO_DANCE | yes | (yes) | on Android this will be stored as DANCING |
| CLIMBING | yes | ||
| COOLDOWN | yes | ||
| CORE_TRAINING | yes | ||
| CRICKET | yes | yes | |
| CROSS_COUNTRY_SKIING | yes | (yes) | on Android this will be stored as SKIING |
| CROSS_TRAINING | yes | ||
| CURLING | yes | ||
| DANCING | yes | yes | on iOS this is DANCE, but name changed here to fit with Android |
| DISC_SPORTS | yes | ||
| DOWNHILL_SKIING | yes | (yes) | on Android this will be stored as SKIING |
| ELLIPTICAL | yes | yes | |
| EQUESTRIAN_SPORTS | yes | ||
| FENCING | yes | yes | |
| FISHING | yes | ||
| FITNESS_GAMING | yes | ||
| FLEXIBILITY | yes | ||
| FRISBEE_DISC | yes | ||
| FUNCTIONAL_STRENGTH_TRAINING | yes | (yes) | on Android this will be stored as STRENGTH_TRAINING |
| GOLF | yes | yes | |
| GUIDED_BREATHING | yes | ||
| GYMNASTICS | yes | yes | |
| HAND_CYCLING | yes | ||
| HANDBALL | yes | yes | |
| HIGH_INTENSITY_INTERVAL_TRAINING | yes | yes | |
| HIKING | yes | yes | |
| HOCKEY | yes | ||
| HUNTING | yes | ||
| JUMP_ROPE | yes | ||
| KICKBOXING | yes | ||
| LACROSSE | yes | ||
| MARTIAL_ARTS | yes | yes | |
| MIND_AND_BODY | yes | ||
| MIXED_CARDIO | yes | ||
| PADDLE_SPORTS | yes | ||
| PARAGLIDING | yes | ||
| PICKLEBALL | yes | ||
| PILATES | yes | yes | |
| PLAY | yes | ||
| PREPARATION_AND_RECOVERY | yes | ||
| RACQUETBALL | yes | yes | |
| ROCK_CLIMBING | (yes) | yes | on iOS this will be stored as CLIMBING |
| ROWING | yes | yes | |
| RUGBY | yes | yes | |
| RUNNING | yes | yes | |
| RUNNING_TREADMILL | (yes) | yes | on iOS this will be stored as RUNNING |
| SAILING | yes | yes | |
| SCUBA_DIVING | yes | ||
| SKATING | yes | yes | On iOS this will be stored as SKATING_SPORTS |
| SKIING | (yes) | yes | on iOS you have to choose between CROSS_COUNTRY_SKIING and DOWNHILL_SKIING |
| SNOW_SPORTS | yes | ||
| SNOWBOARDING | yes | yes | |
| SOCCER | yes | ||
| SOCIAL_DANCE | yes | (yes) | on Android this will be stored as DANCING |
| SOFTBALL | yes | yes | |
| SQUASH | yes | yes | |
| STAIR_CLIMBING | yes | yes | |
| STAIR_CLIMBING_MACHINE | yes | ||
| STAIRS | yes | ||
| STEP_TRAINING | yes | ||
| STRENGTH_TRAINING | (yes) | yes | on iOS you have to choose between FUNCTIONAL_STRENGTH_TRAINING or TRADITIONAL_STRENGTH_TRAINING |
| SURFING | yes | yes | on iOS this is SURFING_SPORTS, but name changed here to fit with Android |
| SWIMMING | yes | (yes) | on Android you have to choose between SWIMMING_OPEN_WATER and SWIMMING_POOL |
| SWIMMING_OPEN_WATER | (yes) | yes | on iOS this will be stored as SWIMMING |
| SWIMMING_POOL | (yes) | yes | on iOS this will be stored as SWIMMING |
| TABLE_TENNIS | yes | yes | |
| TAI_CHI | yes | ||
| TENNIS | yes | yes | |
| TRACK_AND_FIELD | yes | ||
| TRADITIONAL_STRENGTH_TRAINING | yes | (yes) | on Android this will be stored as STRENGTH_TRAINING |
| UNDERWATER_DIVING | yes | ||
| VOLLEYBALL | yes | yes | |
| WALKING | yes | yes | |
| WATER_FITNESS | yes | ||
| WATER_POLO | yes | yes | |
| WATER_SPORTS | yes | ||
| WEIGHTLIFTING | yes | ||
| WHEELCHAIR | (yes) | yes | on iOS you have to choose between WHEELCHAIR_RUN_PACE or WHEELCHAIR_WALK_PACE |
| WHEELCHAIR_RUN_PACE | yes | (yes) | on Android this will be stored as WHEELCHAIR |
| WHEELCHAIR_WALK_PACE | yes | (yes) | on Android this will be stored as WHEELCHAIR |
| WRESTLING | yes | ||
| YOGA | yes | yes | |
| OTHER | yes | yes |
License
This software is copyright (c) the Technical University of Denmark (DTU) and is part of the Copenhagen Research Platform. This software is available 'as-is' under a MIT license.
История изменений
13.3.1
- iOS: Fix issues with app crashing on iOS 15
- iOS: Add support for
AppleSleepingWristTemperature- PR #468 - Android: Add support for
SkinTemperatureRecord(READ/WRITE)
13.3.0
- Add support for
WORKOUT_ROUTE- PR #454 - Android: Add support for
ActivityIntensityRecord(READ/WRITE/Aggregate) - Update to
androidx.health.connect:connect-client:1.2.0-alpha02
13.2.1
No changes - Now the Health package lives in its own repository at https://github.com/carp-dk/carp-health-flutter
13.2.0
- Add get health data by UUID (see
getHealthDataByUUID()) - PR #1193, #1194 - Add delete by UUID (
deleteByUUID()) - Add support for unit conversion in
WeightRecord,HeightRecord,BodyTemperatureRecord, andBloodGlucoseRecord- PR #1212 - Update
compileSDKto 36 - Fix #1261 - Update Gradle to 8.9.1
- Update
org.jetbrains.kotlin.androidto 2.1.0 - Update
androidx.health.connect:connect-clientto 1.1.0-rc03 - Update
device_info_plusto 12.1.0 - Fix #1264
13.1.4
- Fix adding mindfulness resulted in crash in iOS
- Support SPM for iOS
13.1.3
- Fix permissions issues with iOS
- Fix #1231
13.1.2
13.1.1
- Fix #1207 - (Important: Some property names might have changed compared to before for
Nutrition) - Fix #1201
- iOS: Add
APPLE_STAND_TIME,APPLE_STAND_HOUR, andAPPLE_MOVE_TIMEhealth data types (READ ONLY) #1190
13.1.0
- Refactored Android native implementation (No Flutter API changes)
- Android: Add
SPEEDhealth data type - PR #1183 - iOS: Add
WALKING_SPEEDhealth data type - PR #1183 - Add
METER_PER_SECONDhealth data unit
13.0.1
SwiftHealthPlugin (Main Plugin Class)
├── HealthDataReader (Reading health data)
├── HealthDataWriter (Writing health data)
├── HealthDataOperations (Permissions and deletion)
├── HealthUtilities (Helper functions)
└── HealthConstants (Constants and enums)
13.0.0
- Refactored Swift native implementation
12.2.1
- iOS: Add
swift_versionfor add-to-app implementations - PR #1205
12.2.0
- iOS: Add
deviceModelin returned Health data to identify the device that generated the data of the receiver. (in iOSsource_namerepresents the revision of the source responsible for saving the receiver.) - Android: Add read health data in background - PR #1184
- Fix #1169 where
meal_typeproperty inNutritionwas null always - iOS: Add
CARDIO_DANCEHealthDataType - #1146
12.1.0
- Add delete record by UUID method. See function
deleteByUUID(required String uuid, HealthDataType? type) - iOS: Parse metadata to remove unsupported types - PR #1120
- iOS: Add UV Index Types
- Android: Add request access to historic data #1126 - PR #1127
<!-- Add the following permission into AndroidManifest.xml -->
<uses-permission android:name="android.permission.health.READ_HEALTH_DATA_HISTORY"/>
- Android:
- Update
androidx.compose:compose-bomto2025.02.00 - Update
androidx.health.connect:connect-clientto1.1.0-alpha11 - Update
androidx.fragment:fragment-ktxto1.8.6 - Update to Java 11
- Update
- Update example apps
12.0.1
- Update of API and README doc
- Fix #1118
12.0.0
-
BREAKING This release introduces a significant architectural change to the
healthplugin by removing thesingletonpattern.- Dependency Injection for
DeviceInfoPlugin: - The
Healthclass is no longer a singleton. - The
Health()factory constructor is removed. - The
Healthclass now accepts an (optional)DeviceInfoPlugindependency through its constructor, this change was introduced to provide easy mocking of theDeviceInfoclass during unit tests. - This architectural change means that, for the application to work correctly, the
Healthclass MUST be initialized correctly as a global instance. - Impact:
- For most users, no immediate code changes are required but it is paramount to initialize the
Healthclass as a global instance (i.e. do not callHealth()every time but rather define an instancefinal health = Health();).
- For most users, no immediate code changes are required but it is paramount to initialize the
- Dependency Injection for
-
BREAKING (Android) Remove automatic permission request of
DISTANCE_DELTAandTOTAL_CALORIES_BURNEDdata types when requesting permission forWORKOUThealth data type. -
Add
LEAN_BODY_MASSdata type #1078 - PR #1097- The following AndroidManifest values are required to READ/WRITE
LEAN_BODY_MASS:
<uses-permission android:name="android.permission.health.READ_LEAN_BODY_MASS"/> <uses-permission android:name="android.permission.health.WRITE_LEAN_BODY_MASS"/> - The following AndroidManifest values are required to READ/WRITE
-
iOS: Add
WATER_TEMPERATUREandUNDERWATER_DEPTHhealth values #1096 -
iOS: Add support for
Underwater Divingworkout #1096 -
Fix issue where iOS delete not deleting own records - PR #1104
-
Fix issue where
SLEEP_LIGHTtype was not aligned correctly - PR #1086 -
Updated
intlto ^0.20.1 #1092 -
Updated
device_info_plusto ^11.2.0 -
Example app: Updated
permission_handlerto ^11.3.1
11.1.1
- Fix of #1059
11.1.0
- Fix of #1043
- Type-safe JSON deserialization using carp_serializable v. 2.0
11.0.0
- BREAKING Remove Google Fit support in the Android code, as well as Google FIt related dependencies and references throughout the documentation
- Remove
useHealthConnectIfAvailablefrom the parameters ofHealth().configure() - Remove the
disconnectmethod which was previously used to disconnect from Google Fit. - Remove the
flowRatevalue fromwriteBloodOxygenas this is not supported by Health Connect. - Remove support for various
HealthWorkoutActivityTypes which were supported by Google Fit. Some of these do not have suitable alternatives in Google Health Connect (and are not supported on iOS). The list of removed types can be found in PR #1014
- Remove
- BREAKING introduce a new
RecordingMethodenum- This can be used to filter records by automatic or manual entries when fetching data
- You can also specify the recording method to write in the metadata
- Remove
isManualEntryfromHealthDataPointin favor ofrecordingMethod, of which the value is an enumRecordingMethod - Remove
includeManualEntry(previously a boolean) from some of the querying methods in favor ofrecordingMethodsToFilter. - For complete details on relevant changes, see the description of PR #1023
- Add support for all sleep stages across iOS and Android
- Android: Add support for
OTHERworkout type - Cleaned up workout activity types for consistency across iOS and Android, see PR #1020 for a complete list of changes
- iOS: add support for menstruation flow, PR #1008
- Android: Add support for heart rate variability, PR #1009
- iOS: add support for atrial fibrillation burden, PR #1031
- Add support for UUIDs in health records for both HealthKit and Health Connect, PR #1019
- Fix an issue when querying workouts, the native code could respond with an activity that is not supported in the Health package, causing an error - this will fallback to
HealthWorkoutActivityType.other- PR #1016 - Remove deprecated Android v1 embeddings, PR #1021
10.2.0
- Using named parameters in most methods for consistency.
- Added a
HealthPlatformTypeto save which health platform the data originates from (Apple Health, Google Fit, or Google Health Connect). - Android: Improved support for Google Health Connect
- iOS: Add support for saving blood pressure as a correlation, PR #919
10.1.1
- Fix of error in
WorkoutSummaryJSON serialization. - Fix of #934
- Empty value check for calories nutrition, PR #926
10.0.0
- BREAKING The plugin now works as a singleton using
Health()to access it (instead of creating an instance ofHealthFactory).- This entails that the plugin now need to be configured using the
configure()method before use. - The example app has been update to demonstrate this new singleton model.
- This entails that the plugin now need to be configured using the
- Support for new data types:
- Fixed
SleepSessionRecord, PR #928 - Update to API and README docs
- Upgrade to Dart 3.2 and Flutter 3.
- Added Dart linter and fixed a series of type casting issues.
- Using carp_serializable for consistent camel_case and type-safe generation of JSON serialization methods for polymorphic health data type classes.
9.0.0
- Updated HC to comply with Android 14, PR #834 and #882
- Added checks for NullPointerException, closes issue #878
- Updated intl to ^0.19.0
- Upgrade to AGP 8, PR #868
- Added missing google fit workout types, PR #836
- Added pagination in HC, PR #862
- Fix of permission in example app + improvements to doc, PR #875
8.1.0
- Fixed sleep stages on iOS, Issue #803
- Added Nutrition data type, includes PR #679
- Lowered minSDK, Issue #809
8.0.0
- Fixed issue #774, #779
- Merged PR #579, #717, #770
- Upgraded to mavenCentral, upgraded minSDK, compileSDK, targetSDK
- Updated health connect client to 1.1.0
- Added respiratory rate and peripheral perfusion index to HealthConnect
- Minor fixes to requestAuthorization, sleep stage filtering
7.0.1
- Updated dart doc
7.0.0
- Merged PR #722
- Added deep, light, REM, and out of bed sleep to iOS and Android HealthConnect
6.0.0
- Fixed issues #694, #696, #697, #698
- added totalSteps for HealthConnect
- added supplemental oxygen flow rate for blood oxygen saturation on Android
5.0.0
- Added initial support for the new Health Connect API, as Google Fit is being deprecated.
- Does not yet support
revokePermissions,getTotalStepsInInterval.
- Does not yet support
- Changed Intl package version dependency to
^0.17.0to work with flutter stable version. - Updated the example app to handle more buttons.
4.6.0
- Added method for revoking permissions. On Android it uses
disableFit()to remove access to Google Fit -revokePermissions. Documented lack of methods for iOS.
4.5.0
- Updated android sdk, gradle
- Updated
enumToStringto native.name - Update and fixed JSON serialization of HealthDataPoints
- Removed auth request in
writeWorkoutDatato avoid bug when denying the auth. - Merged pull requests #653, #652, #639, #644, #668
- Further developed #644 on android to accommodate having the
writeBloodPressureapi. - Small bug fixes
4.4.0
4.3.0
- upgrade to
device_info_plus: ^8.0.0
4.2.0
- upgrade to
device_info_plus: ^7.0.0
4.1.1
- fix of #572.
4.1.0
- update of
device_info_plus: ^4.0.0 - upgraded to Dart 2.17 and Flutter 3.0
4.0.0
- Large refactor of the
HealthDataPointvalue into genericHealthValueand addedNumericHealthValue,AudiogramHealthValueandWorkoutHealthValue - Added support for Audiograms with
writeAudiogramand ingetHealthDataFromTypes - Added support for Workouts with
writeWorkoutand ingetHealthDataFromTypes - Added all
HealthWorkoutActivityTypes - Added more
HealthDataUnittypes - Fix of #432
- updated documentation in code
- updated documentation in README.md
- updated example app
- cleaned up code
- removed
requestPermissionsas it was essentially a duplicate ofrequestAuthorization
3.4.4
- Fix of #500.
- Added Headache-types to HealthDataTypes on iOS
3.4.3
- fix of #401.
3.4.2
- Resolved concurrent issues with native threads PR#483.
- HealthKit CategorySample PR#485.
- update of API documentation.
3.4.0
- Add sleep in bed to android PR#457.
- Add the android.permission.ACTIVITY_RECOGNITION setup to the README PR#458.
- Fixed (regression) issues with metric and permissions PR#462.
- Get total steps PR#471.
- update of example app to reflect new features.
- update of API documentation.
3.3.1
3.3.0
- Write support on Google Fit and HealthKit PR#430.
3.2.1
- Updated
device_info_plusversion dependency
3.2.0
- added simple
HKWorkoutandExerciseTimesupport PR#421.
3.1.1+1
- added functions to request authorization PR#394
3.1.0
- added sleep data to Android + fix of permissions and initialization PR#372
- testability of HealthDataPoint PR#388.
- update to using the
device_info_plusplugin
3.0.6
- Added two new fields to the
HealthDataPoint-SourceIdandSourceNameand populate when data is read. This allows data points to be disambiguous and in some cases allows us to get more accurate data. For example the number of steps can be reported from Apple Health and Watch and without source data they are aggregated into just "steps" producing an inaccurate result PR#281.
3.0.5
- Null safety in Dart has been implemented
- The plugin supports the Android v2 embedding
3.0.4
- Upgrade to
device_infoversion 2.0.0
3.0.3
- Merged various PRs, mostly smaller fixes
3.0.2
- Upgrade to
device_infoversion 1.0.0
3.0.1+1
- Bugfix regarding BMI from https://github.com/cph-cachet/flutter-plugins/pull/258
3.0.0
- Changed the flow for requesting access and reading data
- Access must be requested manually before reading
- This simplifies the data flow and makes it easier to reason about when debugging
- Data read access is no longer checked for each individual type, but rather on the set of types specified.
2.0.9
- Now handles the case when asking for BMI on Android when no height data has been collected.
2.0.8
- Fixed a merge issue which had deleted the data types added in 2.0.4.
2.0.7
- Fixed a Google sign-in issue, and a type issue on Android (https://github.com/cph-cachet/flutter-plugins/issues/201)
2.0.6
- Fixed a Google sign-in issue. (https://github.com/cph-cachet/flutter-plugins/issues/172)
2.0.5
- Now uses 'device_info' rather than 'device_id' for getting device information
2.0.4+1
- Static analysis, formatting etc.
2.0.4
- Added Sleep data, Water, and Mindfulness.
2.0.3
- The method
requestAuthorizationis now public again.
2.0.2
- Updated the API to take a list of types rather than a single type, when requesting health data.
2.0.1+1
- Removed the need for try-catch on the programmer's end
2.0.1
- Removed UUID and instead introduced a comparison operator
2.0.0
- Changed the API substantially to allow for granular Data Type permissions
1.1.6
Added the following Health Types as per PR #147
- DISTANCE_WALKING_RUNNING
- FLIGHTS_CLIMBED
- MOVE_MINUTES
- DISTANCE_DELTA
1.1.5
- Fixed an issue with google authorization
- See https://github.com/cph-cachet/flutter-plugins/issues/133
1.1.4
- Corrected table of units
1.1.3
- Updated table with units
1.1.2
- Now supports the data type
HEART_RATE_VARIABILITY_SDNNon iOS
1.1.1
- Fixed issue #88 (https://github.com/cph-cachet/flutter-plugins/issues/88)
1.1.0
- Introduced UUID to the HealthDataPoint class
- Re-did the example application
1.0.6
- Fixed a null-check warning in the obj-c code (issue #87)
1.0.5
- Updated gradle-wrapper distribution url
gradle-5.4.1-all.zip - Updated docs
1.0.2
- Updated documentation for Android and Google Fit.
1.0.1
- Streamlined DataType units in Flutter.
