Merge branch 'train-days' into integration

# Conflicts:
#	apps/train/halkyon_train_flutter/lib/src/app/train_paths.dart
#	docs/adr/0030-halkyon-train.md
This commit is contained in:
Tizian 「ティツィアーン」 2026-11-03 23:14:02 +01:00
commit 81adeb91cc
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
2 changed files with 25705 additions and 410 deletions

View file

@ -48,6 +48,8 @@
<uses-permission android:name="android.permission.health.READ_DISTANCE"/>
<uses-permission android:name="android.permission.health.READ_POWER"/>
<uses-permission android:name="android.permission.health.READ_HEALTH_DATA_HISTORY"/>
<!-- The weights other apps wrote, a scale's say (ADR 0030, D64). -->
<uses-permission android:name="android.permission.health.READ_WEIGHT"/>
<uses-feature android:name="android.hardware.location.gps" android:required="false"/>
<uses-feature android:name="android.hardware.sensor.stepdetector" android:required="false"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>

View file

@ -19,6 +19,7 @@ import androidx.health.connect.client.records.PowerRecord
import androidx.health.connect.client.records.Record
import androidx.health.connect.client.records.SpeedRecord
import androidx.health.connect.client.records.StepsCadenceRecord
import androidx.health.connect.client.records.WeightRecord
import androidx.health.connect.client.records.metadata.DataOrigin
import androidx.health.connect.client.request.ChangesTokenRequest
import androidx.health.connect.client.request.ReadRecordsRequest
@ -120,6 +121,7 @@ class HealthConnectBridge(private val activity: Activity) : MethodChannel.Method
call.argument<Number>("end")!!.toLong(),
),
)
"weights" -> result.success(weights((call.arguments as Number).toLong()))
"route" -> route(call.arguments as String, result)
"openSettings" -> {
activity.startActivity(Intent(HealthConnectClient.ACTION_HEALTH_CONNECT_SETTINGS))
@ -238,6 +240,19 @@ class HealthConnectBridge(private val activity: Activity) : MethodChannel.Method
.filter { it.metadata.dataOrigin.packageName != activity.packageName }
.map { HealthRecords.sessionOf(it, appNameOf(it.metadata.dataOrigin.packageName)) }
/** Other apps' weights since [from] (D64): Health Connect's ID, the time in UTC milliseconds, kilograms and the app. */
private suspend fun weights(from: Long): List<Map<String, Any?>> =
readAll(WeightRecord::class, Instant.ofEpochMilli(from), Instant.now().plusSeconds(60), null)
.filter { it.metadata.dataOrigin.packageName != activity.packageName }
.map {
mapOf(
"id" to it.metadata.id,
"at" to it.time.toEpochMilli(),
"kilograms" to it.weight.inKilograms,
"app" to it.metadata.dataOrigin.packageName,
)
}
/** What [app] recorded from [start] to [end]: its heart rate, distance and power. */
private suspend fun samples(app: String, start: Long, end: Long): Map<String, Any?> {
val (from, to) = Instant.ofEpochMilli(start) to Instant.ofEpochMilli(end)
@ -343,6 +358,7 @@ class HealthConnectBridge(private val activity: Activity) : MethodChannel.Method
HealthPermission.getReadPermission(PowerRecord::class),
),
"history" to setOf(HealthPermission.PERMISSION_READ_HEALTH_DATA_HISTORY),
"weight" to setOf(HealthPermission.getReadPermission(WeightRecord::class)),
)
/**