diff --git a/packages/health/README.md b/packages/health/README.md index 12f71cbdc..bbf0cd1fe 100644 --- a/packages/health/README.md +++ b/packages/health/README.md @@ -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; diff --git a/packages/health/android/src/main/kotlin/cachet/plugins/health/HealthPlugin.kt b/packages/health/android/src/main/kotlin/cachet/plugins/health/HealthPlugin.kt index a4761f48f..844d350f6 100644 --- a/packages/health/android/src/main/kotlin/cachet/plugins/health/HealthPlugin.kt +++ b/packages/health/android/src/main/kotlin/cachet/plugins/health/HealthPlugin.kt @@ -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 @@ -743,6 +744,7 @@ class HealthPlugin(private var channel: MethodChannel? = null) : healthConnectData.add( // mapOf( mapOf( + "uuid" to record.metadata.id, "workoutActivityType" to (workoutTypeMap .filterValues { @@ -815,8 +817,7 @@ class HealthPlugin(private var channel: MethodChannel? = null) : convertRecordStage( recStage, dataType, - rec.metadata.dataOrigin - .packageName + rec.metadata ) ) } @@ -847,10 +848,13 @@ class HealthPlugin(private var channel: MethodChannel? = null) : private fun convertRecordStage( stage: SleepSessionRecord.Stage, dataType: String, - sourceName: String + metadata: Metadata ): List> { + var sourceName = metadata.dataOrigin + .packageName return listOf( mapOf( + "uuid" to metadata.id, "stage" to stage.stage, "value" to ChronoUnit.MINUTES.between( @@ -946,6 +950,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is WeightRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.weight .inKilograms, @@ -965,6 +971,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is HeightRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.height .inMeters, @@ -984,6 +992,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is BodyFatRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.percentage .value, @@ -1003,6 +1013,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is StepsRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.count, "date_from" to record.startTime @@ -1020,6 +1032,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is ActiveCaloriesBurnedRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.energy .inKilocalories, @@ -1039,6 +1053,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is HeartRateRecord -> return record.samples.map { mapOf( + "uuid" to + metadata.id, "value" to it.beatsPerMinute, "date_from" to it.time.toEpochMilli(), @@ -1053,6 +1069,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is HeartRateVariabilityRmssdRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.heartRateVariabilityMillis, "date_from" to @@ -1071,6 +1089,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is BodyTemperatureRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.temperature .inCelsius, @@ -1090,6 +1110,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is BodyWaterMassRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.mass .inKilograms, @@ -1109,6 +1131,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is BloodPressureRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to if (dataType == BLOOD_PRESSURE_DIASTOLIC @@ -1134,6 +1158,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is OxygenSaturationRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.percentage .value, @@ -1153,6 +1179,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is BloodGlucoseRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.level .inMilligramsPerDeciliter, @@ -1172,6 +1200,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is DistanceRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.distance .inMeters, @@ -1191,6 +1221,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is HydrationRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.volume .inLiters, @@ -1210,6 +1242,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is TotalCaloriesBurnedRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.energy .inKilocalories, @@ -1229,6 +1263,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is BasalMetabolicRateRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.basalMetabolicRate .inKilocaloriesPerDay, @@ -1248,6 +1284,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is SleepSessionRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "date_from" to record.startTime .toEpochMilli(), @@ -1270,6 +1308,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is RestingHeartRateRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.beatsPerMinute, "date_from" to @@ -1288,6 +1328,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is FloorsClimbedRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.floors, "date_from" to record.startTime @@ -1305,6 +1347,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is RespiratoryRateRecord -> return listOf( mapOf( + "uuid" to + metadata.id, "value" to record.rate, "date_from" to record.time @@ -1322,6 +1366,7 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is NutritionRecord -> return listOf( mapOf( + "uuid" to metadata.id, "calories" to record.energy?.inKilocalories, "protein" to record.protein?.inGrams, "carbs" to record.totalCarbohydrate?.inGrams, @@ -1385,6 +1430,7 @@ class HealthPlugin(private var channel: MethodChannel? = null) : is MenstruationFlowRecord -> return listOf( mapOf( + "uuid" to metadata.id, "value" to record.flow, "date_from" to record.time.toEpochMilli(), "date_to" to record.time.toEpochMilli(), diff --git a/packages/health/lib/health.g.dart b/packages/health/lib/health.g.dart index 7740670ae..13f14c5a6 100644 --- a/packages/health/lib/health.g.dart +++ b/packages/health/lib/health.g.dart @@ -8,6 +8,7 @@ part of 'health.dart'; HealthDataPoint _$HealthDataPointFromJson(Map json) => HealthDataPoint( + uuid: json['uuid'] as String, value: HealthValue.fromJson(json['value'] as Map), type: $enumDecode(_$HealthDataTypeEnumMap, json['type']), unit: $enumDecode(_$HealthDataUnitEnumMap, json['unit']), @@ -28,6 +29,7 @@ HealthDataPoint _$HealthDataPointFromJson(Map json) => Map _$HealthDataPointToJson(HealthDataPoint instance) { final val = { + 'uuid': instance.uuid, 'value': instance.value, 'type': _$HealthDataTypeEnumMap[instance.type]!, 'unit': _$HealthDataUnitEnumMap[instance.unit]!, diff --git a/packages/health/lib/src/health_data_point.dart b/packages/health/lib/src/health_data_point.dart index b98734c5a..ec5a98a9c 100644 --- a/packages/health/lib/src/health_data_point.dart +++ b/packages/health/lib/src/health_data_point.dart @@ -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; @@ -51,6 +54,7 @@ class HealthDataPoint { Map? metadata; HealthDataPoint({ + required this.uuid, required this.value, required this.type, required this.unit, @@ -129,6 +133,7 @@ class HealthDataPoint { ? null : Map.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; @@ -140,6 +145,7 @@ class HealthDataPoint { } return HealthDataPoint( + uuid: uuid ?? "", value: value, type: dataType, unit: unit, @@ -157,6 +163,7 @@ class HealthDataPoint { @override String toString() => """$runtimeType - + uuid: $uuid, value: ${value.toString()}, unit: ${unit.name}, dateFrom: $dateFrom, @@ -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 && @@ -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); } diff --git a/packages/health/lib/src/health_plugin.dart b/packages/health/lib/src/health_plugin.dart index a6232e202..9375e5c81 100644 --- a/packages/health/lib/src/health_plugin.dart +++ b/packages/health/lib/src/health_plugin.dart @@ -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,