@@ -110,6 +110,76 @@ class HealthDataReader(
110110 }
111111 }
112112
113+ /* *
114+ * Retrieves single health data point by given UUID and type.
115+ *
116+ * @param call Method call containing 'UUID' and 'dataTypeKey'
117+ * @param result Flutter result callback returning list of health data maps
118+ */
119+ fun getDataByUUID (call : MethodCall , result : Result ) {
120+ val dataType = call.argument<String >(" dataTypeKey" )!!
121+ val uuid = call.argument<String >(" uuid" )!!
122+ var healthPoint = mapOf<String , Any ?>()
123+
124+ if (! HealthConstants .mapToType.containsKey(dataType)) {
125+ Log .w(" FLUTTER_HEALTH::ERROR" , " Datatype $dataType not found in HC" )
126+ result.success(null )
127+ return
128+ }
129+
130+ val classType = HealthConstants .mapToType[dataType]!!
131+
132+ scope.launch {
133+ try {
134+
135+ Log .i(" FLUTTER_HEALTH" , " Getting $uuid with $classType " )
136+
137+ // Execute the request
138+ val response = healthConnectClient.readRecord(classType, uuid)
139+
140+ // Find the record with the matching UUID
141+ val matchingRecord = response.record
142+
143+ if (matchingRecord != null ) {
144+ // Handle special cases using shared logic
145+ when (dataType) {
146+ WORKOUT -> {
147+ val tempData = mutableListOf<Map <String , Any ?>>()
148+ handleWorkoutData(listOf (matchingRecord), emptyList(), tempData)
149+ healthPoint = if (tempData.isNotEmpty()) tempData[0 ] else mapOf ()
150+ }
151+ SLEEP_SESSION , SLEEP_ASLEEP , SLEEP_AWAKE , SLEEP_AWAKE_IN_BED ,
152+ SLEEP_LIGHT , SLEEP_DEEP , SLEEP_REM , SLEEP_OUT_OF_BED , SLEEP_UNKNOWN -> {
153+ if (matchingRecord is SleepSessionRecord ) {
154+ val tempData = mutableListOf<Map <String , Any ?>>()
155+ handleSleepData(listOf (matchingRecord), emptyList(), dataType, tempData)
156+ healthPoint = if (tempData.isNotEmpty()) tempData[0 ] else mapOf ()
157+ }
158+ }
159+ else -> {
160+ healthPoint = dataConverter.convertRecord(matchingRecord, dataType)[0 ]
161+ }
162+ }
163+
164+ Log .i(
165+ " FLUTTER_HEALTH" ,
166+ " Success: $healthPoint "
167+ )
168+
169+ Handler (context.mainLooper).run { result.success(healthPoint) }
170+ } else {
171+ Log .e(" FLUTTER_HEALTH::ERROR" , " Record not found for UUID: $uuid " )
172+ result.success(null )
173+ }
174+ } catch (e: Exception ) {
175+ Log .e(" FLUTTER_HEALTH::ERROR" , " Error fetching record with UUID: $uuid " )
176+ Log .e(" FLUTTER_HEALTH::ERROR" , e.message ? : " unknown error" )
177+ Log .e(" FLUTTER_HEALTH::ERROR" , e.stackTraceToString())
178+ result.success(null )
179+ }
180+ }
181+ }
182+
113183 /* *
114184 * Retrieves aggregated health data grouped by time intervals.
115185 * Calculates totals, averages, or counts over specified time periods.
@@ -289,18 +359,22 @@ class HealthDataReader(
289359 * by querying related records within the workout time period.
290360 *
291361 * @param records List of ExerciseSessionRecord objects
292- * @param recordingMethodsToFilter Recording methods to exclude
362+ * @param recordingMethodsToFilter Recording methods to exclude (empty list means no filtering)
293363 * @param healthConnectData Mutable list to append processed workout data
294364 */
295365 private suspend fun handleWorkoutData (
296366 records : List <Record >,
297- recordingMethodsToFilter : List <Int >,
367+ recordingMethodsToFilter : List <Int > = emptyList() ,
298368 healthConnectData : MutableList <Map <String , Any ?>>
299369 ) {
300- val filteredRecords = recordingFilter.filterRecordsByRecordingMethods(
301- recordingMethodsToFilter,
370+ val filteredRecords = if (recordingMethodsToFilter.isEmpty()) {
302371 records
303- )
372+ } else {
373+ recordingFilter.filterRecordsByRecordingMethods(
374+ recordingMethodsToFilter,
375+ records
376+ )
377+ }
304378
305379 for (rec in filteredRecords) {
306380 val record = rec as ExerciseSessionRecord
@@ -366,8 +440,8 @@ class HealthDataReader(
366440 " totalSteps" to if (totalSteps == 0.0 ) null else totalSteps,
367441 " totalStepsUnit" to " COUNT" ,
368442 " unit" to " MINUTES" ,
369- " date_from" to rec .startTime.toEpochMilli(),
370- " date_to" to rec .endTime.toEpochMilli(),
443+ " date_from" to record .startTime.toEpochMilli(),
444+ " date_to" to record .endTime.toEpochMilli(),
371445 " source_id" to " " ,
372446 " source_name" to record.metadata.dataOrigin.packageName,
373447 ),
@@ -381,20 +455,24 @@ class HealthDataReader(
381455 * Converts sleep stage enumerations to meaningful duration and type information.
382456 *
383457 * @param records List of SleepSessionRecord objects
384- * @param recordingMethodsToFilter Recording methods to exclude
458+ * @param recordingMethodsToFilter Recording methods to exclude (empty list means no filtering)
385459 * @param dataType Specific sleep data type being requested
386460 * @param healthConnectData Mutable list to append processed sleep data
387461 */
388462 private fun handleSleepData (
389463 records : List <Record >,
390- recordingMethodsToFilter : List <Int >,
464+ recordingMethodsToFilter : List <Int > = emptyList() ,
391465 dataType : String ,
392466 healthConnectData : MutableList <Map <String , Any ?>>
393467 ) {
394- val filteredRecords = recordingFilter.filterRecordsByRecordingMethods(
395- recordingMethodsToFilter,
468+ val filteredRecords = if (recordingMethodsToFilter.isEmpty()) {
396469 records
397- )
470+ } else {
471+ recordingFilter.filterRecordsByRecordingMethods(
472+ recordingMethodsToFilter,
473+ records
474+ )
475+ }
398476
399477 for (rec in filteredRecords) {
400478 if (rec is SleepSessionRecord ) {
0 commit comments