Geschwindigkeit und Anzeigen korrigiert

This commit is contained in:
Thorsten
2026-03-06 10:05:16 +01:00
parent 3d2d68d145
commit a455be8db7
4 changed files with 91 additions and 12 deletions
+8
View File
@@ -15,6 +15,14 @@
</SelectionState> </SelectionState>
<SelectionState runConfigName="gpstracker"> <SelectionState runConfigName="gpstracker">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2026-03-06T08:51:20.686825100Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=28161JEEJR069K" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState> </SelectionState>
</selectionStates> </selectionStates>
</component> </component>
@@ -25,15 +25,20 @@ class GPXManager(private val context: Context) {
timeZone = TimeZone.getTimeZone("UTC") timeZone = TimeZone.getTimeZone("UTC")
}.format(Date(location.time)) }.format(Date(location.time))
val trkpt = """ val sb = StringBuilder()
<trkpt lat="${location.latitude}" lon="${location.longitude}"> sb.append("<trkpt lat=\"${location.latitude}\" lon=\"${location.longitude}\">")
<ele>${location.altitude}</ele> sb.append("<ele>${location.altitude}</ele>")
<time>$time</time> sb.append("<time>$time</time>")
</trkpt> if (location.speed > 0 || location.bearing > 0) {
""".trimIndent() sb.append("<extensions>")
if (location.speed > 0) sb.append("<speed>${location.speed}</speed>")
if (location.bearing > 0) sb.append("<course>${location.bearing}</course>")
sb.append("</extensions>")
}
sb.append("</trkpt>")
val content = file.readText().removeSuffix(getGpxFooter()) val content = file.readText().removeSuffix(getGpxFooter())
file.writeText(content + trkpt + getGpxFooter()) file.writeText(content + sb.toString() + getGpxFooter())
} }
} }
@@ -45,6 +50,12 @@ class GPXManager(private val context: Context) {
return context.filesDir.listFiles { _, name -> name.endsWith(".gpx") }?.toList() ?: emptyList() return context.filesDir.listFiles { _, name -> name.endsWith(".gpx") }?.toList() ?: emptyList()
} }
fun deleteAllFiles(): Int {
val files = getAllFiles()
files.forEach { it.delete() }
return files.size
}
private fun getGpxHeader() = """ private fun getGpxHeader() = """
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="WearGPSTracker" xmlns="http://www.topografix.com/GPX/1/1"> <gpx version="1.1" creator="WearGPSTracker" xmlns="http://www.topografix.com/GPX/1/1">
@@ -25,11 +25,14 @@ class TrackingService : Service() {
private var startTime = 0L private var startTime = 0L
private var lastLocation: Location? = null private var lastLocation: Location? = null
private var job: Job? = null private var job: Job? = null
private var speedSumKmh = 0.0
private var speedCount = 0
data class TrackingData( data class TrackingData(
val durationSeconds: Long = 0, val durationSeconds: Long = 0,
val distanceKm: Double = 0.0, val distanceKm: Double = 0.0,
val speedKmh: Double = 0.0 val speedKmh: Double = 0.0,
val avgSpeedKmh: Double = 0.0
) )
inner class LocalBinder : Binder() { inner class LocalBinder : Binder() {
@@ -65,9 +68,16 @@ class TrackingService : Service() {
lastLocation = location lastLocation = location
val speedKmh = location.speed * 3.6 val speedKmh = location.speed * 3.6
if (speedKmh > 0) {
speedSumKmh += speedKmh
speedCount++
}
val avgSpeedKmh = if (speedCount > 0) speedSumKmh / speedCount else 0.0
_trackingState.value = currentData.copy( _trackingState.value = currentData.copy(
distanceKm = newDistance, distanceKm = newDistance,
speedKmh = speedKmh speedKmh = speedKmh,
avgSpeedKmh = avgSpeedKmh
) )
} }
@@ -86,6 +96,8 @@ class TrackingService : Service() {
gpxManager.startNewSession() gpxManager.startNewSession()
startTime = System.currentTimeMillis() startTime = System.currentTimeMillis()
lastLocation = null lastLocation = null
speedSumKmh = 0.0
speedCount = 0
_trackingState.value = TrackingData() _trackingState.value = TrackingData()
val locationRequest = LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 1000) val locationRequest = LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 1000)
@@ -14,6 +14,8 @@ import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@@ -154,16 +156,18 @@ fun TrackingScreen(navController: NavHostController) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center verticalArrangement = Arrangement.Center,
modifier = Modifier.padding(horizontal = 16.dp)
) { ) {
val hours = trackingData.durationSeconds / 3600 val hours = trackingData.durationSeconds / 3600
val minutes = (trackingData.durationSeconds % 3600) / 60 val minutes = (trackingData.durationSeconds % 3600) / 60
val seconds = trackingData.durationSeconds % 60 val seconds = trackingData.durationSeconds % 60
val timeString = String.format("%02d:%02d:%02d", hours, minutes, seconds) val timeString = String.format("%02d:%02d:%02d", hours, minutes, seconds)
Text(text = timeString, style = MaterialTheme.typography.display1) Text(text = timeString, style = MaterialTheme.typography.title1)
Text(text = String.format("%.2f km", trackingData.distanceKm), style = MaterialTheme.typography.body1) Text(text = String.format("%.2f km", trackingData.distanceKm), style = MaterialTheme.typography.body1)
Text(text = String.format("%.1f km/h", trackingData.speedKmh), style = MaterialTheme.typography.body1) Text(text = String.format("%.1f km/h", trackingData.speedKmh), style = MaterialTheme.typography.body1)
Text(text = String.format("Ø %.1f km/h", trackingData.avgSpeedKmh), style = MaterialTheme.typography.body2)
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
@@ -200,11 +204,47 @@ fun ActivitiesScreen(navController: NavHostController) {
val gpxManager = remember { GPXManager(context) } val gpxManager = remember { GPXManager(context) }
val syncManager = remember { WearSyncManager(context) } val syncManager = remember { WearSyncManager(context) }
var count by remember { mutableIntStateOf(gpxManager.getActivitiesCount()) } var count by remember { mutableIntStateOf(gpxManager.getActivitiesCount()) }
var showDeleteConfirm by remember { mutableStateOf(false) }
if (showDeleteConfirm) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text = "Alle löschen?", style = MaterialTheme.typography.title3)
Spacer(modifier = Modifier.height(12.dp))
Button(
onClick = {
val deleted = gpxManager.deleteAllFiles()
count = 0
showDeleteConfirm = false
Toast.makeText(context, "$deleted Aktivitäten gelöscht", Toast.LENGTH_SHORT).show()
},
colors = ButtonDefaults.buttonColors(backgroundColor = Color.Red),
modifier = Modifier.fillMaxWidth(0.8f)
) {
Text("Ja, löschen", color = Color.White)
}
Spacer(modifier = Modifier.height(8.dp))
Button(
onClick = { showDeleteConfirm = false },
modifier = Modifier.fillMaxWidth(0.8f),
colors = ButtonDefaults.secondaryButtonColors()
) {
Text("Abbrechen")
}
}
}
return
}
val scrollState = rememberScrollState()
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center verticalArrangement = Arrangement.Center,
modifier = Modifier.verticalScroll(scrollState).padding(vertical = 16.dp)
) { ) {
Text(text = "$count Aktivitäten", style = MaterialTheme.typography.title3) Text(text = "$count Aktivitäten", style = MaterialTheme.typography.title3)
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
@@ -230,6 +270,14 @@ fun ActivitiesScreen(navController: NavHostController) {
Text("GPX Sync") Text("GPX Sync")
} }
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Button(
onClick = { showDeleteConfirm = true },
modifier = Modifier.fillMaxWidth(0.8f),
colors = ButtonDefaults.buttonColors(backgroundColor = Color.Red)
) {
Text("Alle löschen", color = Color.White)
}
Spacer(modifier = Modifier.height(8.dp))
Button( Button(
onClick = { navController.popBackStack() }, onClick = { navController.popBackStack() },
modifier = Modifier.fillMaxWidth(0.8f), modifier = Modifier.fillMaxWidth(0.8f),