Skip to content

Commit c6c205e

Browse files
committed
Add SPEED health data type support
1 parent 6f29495 commit c6c205e

File tree

4 files changed

+73
-1
lines changed

4 files changed

+73
-1
lines changed

packages/health/android/src/main/kotlin/cachet/plugins/health/HealthConstants.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ object HealthConstants {
3636
const val WATER = "WATER"
3737
const val WEIGHT = "WEIGHT"
3838
const val TOTAL_CALORIES_BURNED = "TOTAL_CALORIES_BURNED"
39+
const val SPEED = "SPEED"
3940

4041
// Meal types
4142
const val BREAKFAST = "BREAKFAST"
@@ -101,6 +102,7 @@ object HealthConstants {
101102
RESPIRATORY_RATE to RespiratoryRateRecord::class,
102103
TOTAL_CALORIES_BURNED to TotalCaloriesBurnedRecord::class,
103104
MENSTRUATION_FLOW to MenstruationFlowRecord::class,
105+
SPEED to SpeedRecord::class,
104106
)
105107

106108
/**

packages/health/android/src/main/kotlin/cachet/plugins/health/HealthDataConverter.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ class HealthDataConverter {
6262
is HeartRateRecord -> record.samples.map { sample ->
6363
createInstantRecord(metadata, sample.time, sample.beatsPerMinute)
6464
}
65+
66+
is SpeedRecord -> record.samples.map { sample ->
67+
createInstantRecord(metadata, sample.time, sample.speed.inMetersPerSecond)
68+
}
6569

6670
is SleepSessionRecord -> listOf(
6771
createIntervalRecord(

packages/health/android/src/main/kotlin/cachet/plugins/health/HealthDataWriter.kt

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,56 @@ class HealthDataWriter(
352352
}
353353
}
354354

355-
// ---------- Private Methods ----------
355+
/**
356+
* Writes speed/velocity data with multiple samples to Health Connect.
357+
* Creates a SpeedRecord containing time-series speed measurements captured during
358+
* activities like running, cycling, or walking. Each sample represents the user's
359+
* instantaneous speed at a specific moment within the recording period.
360+
*
361+
* @param call Method call containing startTime, endTime, recordingMethod,
362+
* samples: List<Map<String, Any>> List of speed measurements, each
363+
* containing: time, speed (m/s)
364+
*
365+
* @param result Flutter result callback returning boolean success status
366+
*/
367+
fun writeMultipleSpeedData(call: MethodCall, result: Result) {
368+
val startTime = call.argument<Long>("startTime")!!
369+
val endTime = call.argument<Long>("endTime")!!
370+
val samples = call.argument<List<Map<String, Any>>>("samples")!!
371+
val recordingMethod = call.argument<Int>("recordingMethod")!!
372+
373+
scope.launch {
374+
try {
375+
val speedSamples = samples.map { sample ->
376+
SpeedRecord.Sample(
377+
time = Instant.ofEpochMilli(sample["time"] as Long),
378+
speed = Velocity.metersPerSecond(sample["speed"] as Double)
379+
)
380+
}
381+
382+
val speedRecord = SpeedRecord(
383+
startTime = Instant.ofEpochMilli(startTime),
384+
endTime = Instant.ofEpochMilli(endTime),
385+
samples = speedSamples,
386+
startZoneOffset = null,
387+
endZoneOffset = null,
388+
metadata = Metadata(recordingMethod = recordingMethod),
389+
)
390+
391+
healthConnectClient.insertRecords(listOf(speedRecord))
392+
result.success(true)
393+
Log.i(
394+
"FLUTTER_HEALTH::SUCCESS",
395+
"Successfully wrote ${speedSamples.size} speed samples"
396+
)
397+
} catch (e: Exception) {
398+
Log.e("FLUTTER_HEALTH::ERROR", "Error writing speed data: ${e.message}")
399+
result.success(false)
400+
}
401+
}
402+
}
403+
404+
// ---------- Private Methods ----------
356405

357406
/**
358407
* Creates appropriate Health Connect record objects based on data type.
@@ -549,6 +598,20 @@ class HealthDataWriter(
549598
zoneOffset = null,
550599
metadata = Metadata(recordingMethod = recordingMethod),
551600
)
601+
602+
SPEED -> SpeedRecord(
603+
startTime = Instant.ofEpochMilli(startTime),
604+
endTime = Instant.ofEpochMilli(endTime),
605+
samples = listOf(
606+
SpeedRecord.Sample(
607+
time = Instant.ofEpochMilli(startTime),
608+
speed = Velocity.metersPerSecond(value),
609+
)
610+
),
611+
startZoneOffset = null,
612+
endZoneOffset = null,
613+
metadata = Metadata(recordingMethod = recordingMethod),
614+
)
552615

553616
BLOOD_PRESSURE_SYSTOLIC -> {
554617
Log.e("FLUTTER_HEALTH::ERROR", "You must use the [writeBloodPressure] API")
@@ -630,6 +693,7 @@ class HealthDataWriter(
630693
private const val BLOOD_PRESSURE_DIASTOLIC = "BLOOD_PRESSURE_DIASTOLIC"
631694
private const val WORKOUT = "WORKOUT"
632695
private const val NUTRITION = "NUTRITION"
696+
private const val SPEED = "SPEED"
633697

634698
// Sleep types
635699
private const val SLEEP_ASLEEP = "SLEEP_ASLEEP"

packages/health/android/src/main/kotlin/cachet/plugins/health/HealthPlugin.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ class HealthPlugin(private var channel: MethodChannel? = null) :
150150
"writeBloodOxygen" -> dataWriter.writeBloodOxygen(call, result)
151151
"writeMenstruationFlow" -> dataWriter.writeMenstruationFlow(call, result)
152152
"writeMeal" -> dataWriter.writeMeal(call, result)
153+
// TODO: Add support for multiple speed for iOS as well
154+
// "writeMultipleSpeed" -> dataWriter.writeMultipleSpeedData(call, result)
153155

154156
// Deleting data
155157
"delete" -> dataOperations.deleteData(call, result)

0 commit comments

Comments
 (0)