Skip to content

Commit

Permalink
[Health] Add UUID field to HealthDataPoint (#1019)
Browse files Browse the repository at this point in the history
* Remove Google Fit and imports from Android code

* Formatting

* Remove Google Fit column from readme

* Remove support for Google Fit types not supported by Health Connect

* Remove more Google Fit workout types

* Remove references to Google Fit, remove `useHealthConnectIfAvailable`

* Remove `disconect` method channel

* Remove `flowRate` from `writeBloodOxygen` as it is not supported in Health Connect

* Remove more unsupported workout types

* Add missing import

* Remove Google Fit as dependency

* Add notice in README

* Improve logging for HC permission callback

* Update some documentation

* Android: Fix `requestAuthorization` not returning a result on success

* Remove additional workout types that are not supported

* Remove another workout type

* Add missing unimplemented method

* Add `uuid` field to `HealthDataPoint` and include it in datapoints

* Update README.md

---------

Co-authored-by: bardram <[email protected]>
  • Loading branch information
SlimShadyIAm and bardram authored Aug 29, 2024
1 parent b70d1d7 commit 4b19432
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 4 deletions.
1 change: 1 addition & 0 deletions packages/health/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ Below is a simplified flow of how to use the plugin.
A [`HealthDataPoint`](https://pub.dev/documentation/health/latest/health/HealthDataPoint-class.html) object contains the following data fields:

```dart
String uuid;
HealthValue value;
HealthDataType type;
HealthDataUnit unit;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import androidx.health.connect.client.records.MealType.MEAL_TYPE_DINNER
import androidx.health.connect.client.records.MealType.MEAL_TYPE_LUNCH
import androidx.health.connect.client.records.MealType.MEAL_TYPE_SNACK
import androidx.health.connect.client.records.MealType.MEAL_TYPE_UNKNOWN
import androidx.health.connect.client.records.metadata.Metadata
import androidx.health.connect.client.request.AggregateGroupByDurationRequest
import androidx.health.connect.client.request.AggregateRequest
import androidx.health.connect.client.request.ReadRecordsRequest
Expand Down Expand Up @@ -743,6 +744,7 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
healthConnectData.add(
// mapOf(
mapOf<String, Any?>(
"uuid" to record.metadata.id,
"workoutActivityType" to
(workoutTypeMap
.filterValues {
Expand Down Expand Up @@ -815,8 +817,7 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
convertRecordStage(
recStage,
dataType,
rec.metadata.dataOrigin
.packageName
rec.metadata
)
)
}
Expand Down Expand Up @@ -847,10 +848,13 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
private fun convertRecordStage(
stage: SleepSessionRecord.Stage,
dataType: String,
sourceName: String
metadata: Metadata
): List<Map<String, Any>> {
var sourceName = metadata.dataOrigin
.packageName
return listOf(
mapOf<String, Any>(
"uuid" to metadata.id,
"stage" to stage.stage,
"value" to
ChronoUnit.MINUTES.between(
Expand Down Expand Up @@ -946,6 +950,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is WeightRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to
record.weight
.inKilograms,
Expand All @@ -965,6 +971,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is HeightRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to
record.height
.inMeters,
Expand All @@ -984,6 +992,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is BodyFatRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to
record.percentage
.value,
Expand All @@ -1003,6 +1013,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is StepsRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to record.count,
"date_from" to
record.startTime
Expand All @@ -1020,6 +1032,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is ActiveCaloriesBurnedRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to
record.energy
.inKilocalories,
Expand All @@ -1039,6 +1053,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is HeartRateRecord ->
return record.samples.map {
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to it.beatsPerMinute,
"date_from" to
it.time.toEpochMilli(),
Expand All @@ -1053,6 +1069,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is HeartRateVariabilityRmssdRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to
record.heartRateVariabilityMillis,
"date_from" to
Expand All @@ -1071,6 +1089,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is BodyTemperatureRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to
record.temperature
.inCelsius,
Expand All @@ -1090,6 +1110,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is BodyWaterMassRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to
record.mass
.inKilograms,
Expand All @@ -1109,6 +1131,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is BloodPressureRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to
if (dataType ==
BLOOD_PRESSURE_DIASTOLIC
Expand All @@ -1134,6 +1158,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is OxygenSaturationRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to
record.percentage
.value,
Expand All @@ -1153,6 +1179,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is BloodGlucoseRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to
record.level
.inMilligramsPerDeciliter,
Expand All @@ -1172,6 +1200,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is DistanceRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to
record.distance
.inMeters,
Expand All @@ -1191,6 +1221,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is HydrationRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to
record.volume
.inLiters,
Expand All @@ -1210,6 +1242,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is TotalCaloriesBurnedRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to
record.energy
.inKilocalories,
Expand All @@ -1229,6 +1263,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is BasalMetabolicRateRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to
record.basalMetabolicRate
.inKilocaloriesPerDay,
Expand All @@ -1248,6 +1284,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is SleepSessionRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"date_from" to
record.startTime
.toEpochMilli(),
Expand All @@ -1270,6 +1308,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is RestingHeartRateRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to
record.beatsPerMinute,
"date_from" to
Expand All @@ -1288,6 +1328,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is FloorsClimbedRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to record.floors,
"date_from" to
record.startTime
Expand All @@ -1305,6 +1347,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is RespiratoryRateRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to
metadata.id,
"value" to record.rate,
"date_from" to
record.time
Expand All @@ -1322,6 +1366,7 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is NutritionRecord ->
return listOf(
mapOf<String, Any?>(
"uuid" to metadata.id,
"calories" to record.energy?.inKilocalories,
"protein" to record.protein?.inGrams,
"carbs" to record.totalCarbohydrate?.inGrams,
Expand Down Expand Up @@ -1385,6 +1430,7 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
is MenstruationFlowRecord ->
return listOf(
mapOf<String, Any>(
"uuid" to metadata.id,
"value" to record.flow,
"date_from" to record.time.toEpochMilli(),
"date_to" to record.time.toEpochMilli(),
Expand Down
2 changes: 2 additions & 0 deletions packages/health/lib/health.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion packages/health/lib/src/health_data_point.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ enum HealthPlatformType { appleHealth, googleHealthConnect }
/// as value.
@JsonSerializable(fieldRename: FieldRename.snake, includeIfNull: false)
class HealthDataPoint {
/// UUID of the data point.
String uuid;

/// The quantity value of the data point
HealthValue value;

Expand Down Expand Up @@ -51,6 +54,7 @@ class HealthDataPoint {
Map<String, dynamic>? metadata;

HealthDataPoint({
required this.uuid,
required this.value,
required this.type,
required this.unit,
Expand Down Expand Up @@ -129,6 +133,7 @@ class HealthDataPoint {
? null
: Map<String, dynamic>.from(dataPoint['metadata'] as Map);
final unit = dataTypeToUnit[dataType] ?? HealthDataUnit.UNKNOWN_UNIT;
final String? uuid = dataPoint["uuid"] as String?;

// Set WorkoutSummary, if available.
WorkoutSummary? workoutSummary;
Expand All @@ -140,6 +145,7 @@ class HealthDataPoint {
}

return HealthDataPoint(
uuid: uuid ?? "",
value: value,
type: dataType,
unit: unit,
Expand All @@ -157,6 +163,7 @@ class HealthDataPoint {

@override
String toString() => """$runtimeType -
uuid: $uuid,
value: ${value.toString()},
unit: ${unit.name},
dateFrom: $dateFrom,
Expand All @@ -173,6 +180,7 @@ class HealthDataPoint {
@override
bool operator ==(Object other) =>
other is HealthDataPoint &&
uuid == other.uuid &&
value == other.value &&
unit == other.unit &&
dateFrom == other.dateFrom &&
Expand All @@ -186,6 +194,6 @@ class HealthDataPoint {
metadata == other.metadata;

@override
int get hashCode => Object.hash(value, unit, dateFrom, dateTo, type,
int get hashCode => Object.hash(uuid, value, unit, dateFrom, dateTo, type,
sourcePlatform, sourceDeviceId, sourceId, sourceName, metadata);
}
1 change: 1 addition & 0 deletions packages/health/lib/src/health_plugin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ class Health {
(weights[i].value as NumericHealthValue).numericValue.toDouble() /
(h * h);
final x = HealthDataPoint(
uuid: '',
value: NumericHealthValue(numericValue: bmiValue),
type: dataType,
unit: unit,
Expand Down

0 comments on commit 4b19432

Please sign in to comment.