Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Health 12.0.0 #1117

Merged
merged 63 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from 62 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
0b89660
Register WorkoutHealthValue
avargas-btf Sep 25, 2024
75d0b03
Remove automatically added workout permissions
ciriousjoker Oct 5, 2024
2009d03
Fix `HealthDataType was not aligned correctly` when adding SLEEP_LIGH…
sla-000 Nov 23, 2024
0c6aadf
ignore sdkman env
iarata Nov 25, 2024
603c0f9
Merge pull request #1 from iarata/health-12/example-update
iarata Nov 25, 2024
0284846
Update AppDelegate.swift to use @main instead of @UIApplicationMain
iarata Nov 26, 2024
bc9f07c
Comment out ECG-related HealthDataTypes in util.dart since iOS will t…
iarata Nov 27, 2024
19aa01d
Refactor HealthApp widget and improve debug output formatting
iarata Nov 27, 2024
51bd9a6
Merge pull request #2 from iarata/health-12/example-update
iarata Nov 27, 2024
5e39721
Health data query to use HKStatisticsCollectionQuery instead of HKSta…
iarata Nov 28, 2024
8aa68c4
Merge pull request #3 from iarata/health-12/1072-HKStats
iarata Nov 28, 2024
c542556
fixed hasPermissions call. If types have permissions result should be…
ifuterman Dec 4, 2024
cb26018
Updated device_info_plus version dependency
Dec 11, 2024
c52e21b
Merge branch 'cph-cachet:master' into master
arodriguez1996 Dec 12, 2024
079de1b
[Health] Add lean mass data type
cachapa Nov 12, 2024
8950271
Add missing conversion from LeanMassRecord
cachapa Nov 14, 2024
aebf515
Fix wrong field name in Android
cachapa Nov 15, 2024
26c15b6
Fix wrong type name in iOS
cachapa Nov 15, 2024
a0de7bd
Fix weight type
cachapa Nov 16, 2024
d198e10
Merge pull request #1100 from iarata/health-12
iarata Dec 18, 2024
2578bc2
remove non-null check for name
andnlv Dec 25, 2024
988cce8
Deleting entries only selects own entries
bernd70 Dec 28, 2024
c1ddc2c
Undid whitespace changes
bernd70 Dec 28, 2024
5a605c5
Merge pull request #1104 from bernd70/master
iarata Jan 3, 2025
d107e95
Merge pull request #1105 from cph-cachet/health-12/1104-ios-deletes
iarata Jan 4, 2025
289646b
Update CHANGELOG for version 12.0.0
iarata Jan 4, 2025
dcdba9e
Update dependencies: intl to ^0.20.1, device_info_plus to ^11.2.0, an…
iarata Jan 4, 2025
22102f4
Merge pull request #1106 from cph-cachet/health-12/1092-update-intl
iarata Jan 4, 2025
97ad00d
Merge pull request #1103 from andnlv/master
iarata Jan 4, 2025
dd5d5f9
Fix null handling for record name in HealthPlugin
iarata Jan 5, 2025
1feba56
Merge pull request #1107 from cph-cachet/health-12/950-nullpoint
iarata Jan 5, 2025
7a98254
Update CHANGELOG.md to include fixes for issues #950 and #1104
iarata Jan 5, 2025
45edda0
Merge branch 'iarata/health-12' into add_lean_mass
iarata Jan 5, 2025
d138c26
Merge pull request #1097 from cachapa/add_lean_mass
iarata Jan 5, 2025
f9e86e8
Add lean body mass data type and permissions; update example app
iarata Jan 5, 2025
b6a9a4f
Update CHANGELOG.md with AndroidManifest permissions for LEAN_BODY_MASS
iarata Jan 5, 2025
54b8fbf
Add support for WaterTemperature and UnderwaterDepth data types and U…
iarata Jan 6, 2025
4017e03
Merge pull request #1109 from cph-cachet/health-12/1096-underwater-di…
iarata Jan 6, 2025
7a4d121
Merge branch 'iarata/health-12' into health-12/1097-lean-mass
iarata Jan 6, 2025
ecd36d4
Update build for LEAN_BODY_MASS data type
iarata Jan 6, 2025
36ccf84
Merge pull request #1108 from cph-cachet/health-12/1097-lean-mass Clo…
iarata Jan 6, 2025
b6f53e1
Merge branch 'health-12/1095-update-device-info' into master
iarata Jan 7, 2025
10df626
Merge pull request #1095 from PeteRyo0517/master
iarata Jan 7, 2025
574f2de
Merge pull request #1110 from cph-cachet/health-12/1095-update-device…
iarata Jan 7, 2025
478a312
Merge pull request #1091 from ifuterman/master
iarata Jan 7, 2025
a1ee70e
Update CHANGELOG.md to include fixes for issues #1047 and #939
iarata Jan 7, 2025
a364d98
Merge pull request #1111 from cph-cachet/health-12/1091-hasPermission
iarata Jan 7, 2025
d659be9
Merge pull request #1055 from dieringe/dieringe_health_11.1.0
iarata Jan 7, 2025
80af770
chore: update CHANGELOG.md for breaking change in permission requests…
iarata Jan 7, 2025
c9a634e
Merge pull request #1112 from cph-cachet/health-12/1055-remove-auto-w…
iarata Jan 7, 2025
7a8d800
Merge pull request #1086 from sla-000/patch-1
iarata Jan 7, 2025
86a8fac
chore: update CHANGELOG.md to include fix for SLEEP_LIGHT type alignm…
iarata Jan 7, 2025
35cd46c
feat: refactor Health class to remove singleton pattern and enable de…
iarata Jan 9, 2025
8b34d36
test: clean up health_test.dart
iarata Jan 9, 2025
65c43fc
Merge pull request #1052 from arodriguez1996/master
iarata Jan 9, 2025
87745f3
chore: update CHANGELOG.md to include fix for issue #1051
iarata Jan 9, 2025
44aae2c
Merge pull request #1115 from cph-cachet/health-12/1052-workouthealth
iarata Jan 9, 2025
f3fa6f0
Merge branch 'iarata/health-12' into health-12/test
iarata Jan 9, 2025
8f78845
chore: update CHANGELOG.md
iarata Jan 9, 2025
90d9502
chore: update CHANGELOG.md
iarata Jan 9, 2025
028b74b
chore: update CHANGELOG.md
iarata Jan 9, 2025
594322e
Merge pull request #1114 from cph-cachet/health-12/test
bardram Jan 15, 2025
7c33275
Small updates to documentation and improving on pub.dev scores
bardram Jan 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,5 @@ app.*.symbols
!/dev/ci/**/Gemfile.lock
packages/app_usage/example/.flutter-plugins-dependencies
packages/app_usage/example/.flutter-plugins-dependencies

.sdkmanrc
31 changes: 31 additions & 0 deletions packages/health/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
## 12.0.0

* **BREAKING** This release introduces a significant architectural change to the `health` plugin by removing the `singleton` pattern.
* **Dependency Injection for `DeviceInfoPlugin`**:
- The `Health` class is no longer a singleton.
- The `Health()` factory constructor is removed.
- The `Health` class now accepts an (optional) `DeviceInfoPlugin` dependency through its constructor, this change was introduced to provide easy mocking of the `DeviceInfo` class during unit tests.
- This architectural change means that, for the application to work correctly, the `Health` class *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 `Health` class as a global instance (i.e. do not call `Health()` every time but rather define an instance `final health = Health();`).
* **BREAKING** (Android) Remove automatic permission request of `DISTANCE_DELTA` and `TOTAL_CALORIES_BURNED` data types when requesting permission for `WORKOUT` health data type.
* For `WORKOUT`s that require above permissions, now those need to be requested manually.
* Fix [#984](https://github.com/cph-cachet/flutter-plugins/issues/984) - PR [#1055](https://github.com/cph-cachet/flutter-plugins/pull/1055)
* Add `LEAN_BODY_MASS` data type [#1078](https://github.com/cph-cachet/flutter-plugins/issues/1078) - PR [#1097](https://github.com/cph-cachet/flutter-plugins/pull/1097)
* The following AndroidManifest values are required to READ/WRITE `LEAN_BODY_MASS`:
```XML
<uses-permission android:name="android.permission.health.READ_LEAN_BODY_MASS"/>
<uses-permission android:name="android.permission.health.WRITE_LEAN_BODY_MASS"/>
```
* iOS: Add `WATER_TEMPERATURE` and `UNDERWATER_DEPTH` health values [#1096](https://github.com/cph-cachet/flutter-plugins/issues/1096)
* iOS: Add support for `Underwater Diving` workout [#1096](https://github.com/cph-cachet/flutter-plugins/issues/1096)
* Fix [#1072](https://github.com/cph-cachet/flutter-plugins/issues/1072) and [#1074](https://github.com/cph-cachet/flutter-plugins/issues/1074)
* Fix issue where iOS delete not deleting own records - PR [#1104](https://github.com/cph-cachet/flutter-plugins/pull/1104)
* Fix [#950](https://github.com/cph-cachet/flutter-plugins/issues/950) - PR [#1103](https://github.com/cph-cachet/flutter-plugins/pull/1103)
* Fix [#1047](https://github.com/cph-cachet/flutter-plugins/issues/1047) and [#939](https://github.com/cph-cachet/flutter-plugins/issues/939) - PR [#1091](https://github.com/cph-cachet/flutter-plugins/pull/1091)
* Fix issue where `SLEEP_LIGHT` type was not aligned correctly - PR [#1086](https://github.com/cph-cachet/flutter-plugins/pull/1086)
* Fix [#1051](https://github.com/cph-cachet/flutter-plugins/issues/1051) - PR [#1052](https://github.com/cph-cachet/flutter-plugins/pull/1052)
* Updated `intl` to ^0.20.1 [#1092](https://github.com/cph-cachet/flutter-plugins/issues/1092)
* Updated `device_info_plus` to ^11.2.0
* Example app: Updated `permission_handler` to ^11.3.1

## 11.1.1

* Fix of [#1059](https://github.com/cph-cachet/flutter-plugins/issues/1059)
Expand Down
5 changes: 5 additions & 0 deletions packages/health/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,10 @@ The plugin supports the following [`HealthDataType`](https://pub.dev/documentati
| 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 |
| UNDERWATER_DEPTH | METER | yes | | Related to/Requires Apple Watch Ultra's Underwater Diving Workout |
| LEAN_BODY_MASS | KILOGRAMS | yes | yes | |

## Workout Types

Expand Down Expand Up @@ -443,6 +447,7 @@ The plugin supports the following [`HealthWorkoutActivityType`](https://pub.dev/
| 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 | | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const val BLOOD_OXYGEN = "BLOOD_OXYGEN"
const val BLOOD_PRESSURE_DIASTOLIC = "BLOOD_PRESSURE_DIASTOLIC"
const val BLOOD_PRESSURE_SYSTOLIC = "BLOOD_PRESSURE_SYSTOLIC"
const val BODY_FAT_PERCENTAGE = "BODY_FAT_PERCENTAGE"
const val LEAN_BODY_MASS = "LEAN_BODY_MASS"
const val BODY_TEMPERATURE = "BODY_TEMPERATURE"
const val BODY_WATER_MASS = "BODY_WATER_MASS"
const val DISTANCE_DELTA = "DISTANCE_DELTA"
Expand Down Expand Up @@ -544,38 +545,6 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
),
)
}
// Workout also needs distance and total energy burned too
if (typeKey == WORKOUT) {
if (access == 0) {
permList.addAll(
listOf(
HealthPermission.getReadPermission(
DistanceRecord::class
),
HealthPermission.getReadPermission(
TotalCaloriesBurnedRecord::class
),
),
)
} else {
permList.addAll(
listOf(
HealthPermission.getReadPermission(
DistanceRecord::class
),
HealthPermission.getReadPermission(
TotalCaloriesBurnedRecord::class
),
HealthPermission.getWritePermission(
DistanceRecord::class
),
HealthPermission.getWritePermission(
TotalCaloriesBurnedRecord::class
),
),
)
}
}
}
scope.launch {
result.success(
Expand Down Expand Up @@ -629,38 +598,6 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
),
)
}
// Workout also needs distance and total energy burned too
if (typeKey == WORKOUT) {
if (access == 0) {
permList.addAll(
listOf(
HealthPermission.getReadPermission(
DistanceRecord::class
),
HealthPermission.getReadPermission(
TotalCaloriesBurnedRecord::class
),
),
)
} else {
permList.addAll(
listOf(
HealthPermission.getReadPermission(
DistanceRecord::class
),
HealthPermission.getReadPermission(
TotalCaloriesBurnedRecord::class
),
HealthPermission.getWritePermission(
DistanceRecord::class
),
HealthPermission.getWritePermission(
TotalCaloriesBurnedRecord::class
),
),
)
}
}
}
if (healthConnectRequestPermissionsLauncher == null) {
result.success(false)
Expand Down Expand Up @@ -1083,6 +1020,29 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
),
)

is LeanBodyMassRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to
record.mass
.inKilograms,
"date_from" to
record.time
.toEpochMilli(),
"date_to" to
record.time
.toEpochMilli(),
"source_id" to "",
"source_name" to
metadata.dataOrigin
.packageName,
"recording_method" to
metadata.recordingMethod
),
)

is StepsRecord ->
return listOf(
mapOf<String, Any>(
Expand Down Expand Up @@ -1516,7 +1476,7 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
"sugar" to record.sugar?.inGrams,
"water" to null,
"zinc" to record.zinc?.inGrams,
"name" to record.name!!,
"name" to (record.name ?: ""),
"meal_type" to
(mapTypeToMealType[
record.mealType]
Expand Down Expand Up @@ -1596,6 +1556,22 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
),
)

LEAN_BODY_MASS ->
LeanBodyMassRecord(
time =
Instant.ofEpochMilli(
startTime
),
mass =
Mass.kilograms(
value
),
zoneOffset = null,
metadata = Metadata(
recordingMethod = recordingMethod,
),
)

HEIGHT ->
HeightRecord(
time =
Expand Down Expand Up @@ -2398,6 +2374,7 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
private val mapToType =
hashMapOf(
BODY_FAT_PERCENTAGE to BodyFatRecord::class,
LEAN_BODY_MASS to LeanBodyMassRecord::class,
HEIGHT to HeightRecord::class,
WEIGHT to WeightRecord::class,
STEPS to StepsRecord::class,
Expand Down Expand Up @@ -2438,7 +2415,6 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
// "BasalMetabolicRate" to BasalMetabolicRateRecord::class,
// "BloodGlucose" to BloodGlucoseRecord::class,
// "BloodPressure" to BloodPressureRecord::class,
// "BodyFat" to BodyFatRecord::class,
// "BodyTemperature" to BodyTemperatureRecord::class,
// "BoneMass" to BoneMassRecord::class,
// "CervicalMucus" to CervicalMucusRecord::class,
Expand All @@ -2451,7 +2427,6 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
// "HeartRate" to HeartRateRecord::class,
// "Height" to HeightRecord::class,
// "Hydration" to HydrationRecord::class,
// "LeanBodyMass" to LeanBodyMassRecord::class,
// "MenstruationPeriod" to MenstruationPeriodRecord::class,
// "Nutrition" to NutritionRecord::class,
// "OvulationTest" to OvulationTestRecord::class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
<uses-permission android:name="android.permission.health.BODY_SENSORS"/>
<uses-permission android:name="android.permission.health.READ_MENSTRUATION"/>
<uses-permission android:name="android.permission.health.WRITE_MENSTRUATION"/>
<uses-permission android:name="android.permission.health.READ_LEAN_BODY_MASS"/>
<uses-permission android:name="android.permission.health.WRITE_LEAN_BODY_MASS"/>

<application android:label="health_example"
android:icon="@mipmap/ic_launcher">
Expand Down
52 changes: 49 additions & 3 deletions packages/health/example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
8AB8966E9F27B6C816D51EA9 /* [CP] Embed Pods Frameworks */,
99FD4B47838A33EC942FDC35 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
Expand Down Expand Up @@ -271,6 +272,24 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
99FD4B47838A33EC942FDC35 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/permission_handler_apple/permission_handler_apple_privacy.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/permission_handler_apple_privacy.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
AFF7CCF5217A091E1625CD54 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
Expand All @@ -293,6 +312,24 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
FEE6262278064D703A8D8D21 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/permission_handler_apple/permission_handler_apple_privacy.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/permission_handler_apple_privacy.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
Expand Down Expand Up @@ -394,7 +431,10 @@
);
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
Expand Down Expand Up @@ -531,7 +571,10 @@
);
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
Expand Down Expand Up @@ -564,7 +607,10 @@
);
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
Expand Down
2 changes: 1 addition & 1 deletion packages/health/example/ios/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import UIKit
import Flutter

@UIApplicationMain
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
Expand Down
Loading
Loading