Der Kotlin -Tachometer ergibt keine korrekte GeschwindigkeitAndroid

Forum für diejenigen, die für Android programmieren
Anonymous
 Der Kotlin -Tachometer ergibt keine korrekte Geschwindigkeit

Post by Anonymous »

Meine Android -App verfügt über einen Tacho, der zeigt, wie schnell der Benutzer fährt. Es funktioniert jedoch nicht reibungslos. Es zeigt die Geschwindigkeit, aber nicht die genaue Geschwindigkeit und aktualisiert die Geschwindigkeit nicht reibungslos. < /P>
mache ich hier etwas falsch? Gibt es eine andere Möglichkeit, Benutzergeschwindigkeit zu holen? < /P>

Code: Select all

class SpeedometerVM(application: Application) : AndroidViewModel(application) {

private val _speed = MutableStateFlow(0f)  // Speed in km/h
val speed = _speed.asStateFlow()

private val _isActive = MutableStateFlow(false)
val isActive = _isActive.asStateFlow()

private val _accelerationStatus =
MutableStateFlow("Neutral") // Acceleration/Deceleration status
val accelerationStatus = _accelerationStatus.asStateFlow()

// Variable to store previous speed with timestamp for more accurate acceleration calculation
private var previousSpeed = 0f
private var lastUpdateTime = 0L

private val fusedLocationClient by lazy {
LocationServices.getFusedLocationProviderClient(getApplication())
}

// Keep a reference to the callback so we can remove it later
private val locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
locationResult.lastLocation?.let { location ->
val currentTimestamp = System.currentTimeMillis()
val speedInMetersPerSecond = location.speed

// Only update if we have a valid speed reading
if (location.hasSpeed()) {
val speedInKmPerHour = speedInMetersPerSecond * 3.6f // Convert m/s to km/h

// Apply a small smoothing filter to reduce jitter
val smoothedSpeed = if (_speed.value == 0f) {
speedInKmPerHour
} else {
_speed.value * 0.7f + speedInKmPerHour * 0.3f
}

_speed.value = smoothedSpeed

// If enough time has passed, calculate acceleration status
if (lastUpdateTime > 0 && (currentTimestamp - lastUpdateTime) > 500) {
val speedDiff = smoothedSpeed - previousSpeed

// Only update status if change exceeds threshold
val newStatus = when {
speedDiff > 0.5 -> "Accelerating"
speedDiff < -0.5 -> "Decelerating"
else -> "Neutral"
}

if (newStatus != _accelerationStatus.value) {
_accelerationStatus.value = newStatus
}
}

// Update the previous values
previousSpeed = smoothedSpeed
lastUpdateTime = currentTimestamp
}
}
}
}

fun startLocationUpdates() = registerLocationUpdates()

private fun registerLocationUpdates() {
val locationRequest = LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 1000L)
.setMinUpdateIntervalMillis(500) // Set minimum update time
.setMaxUpdateDelayMillis(2000) // Set maximum delay
.build()
viewModelScope.launch {
try {
fusedLocationClient.requestLocationUpdates(
locationRequest,
locationCallback,
Looper.getMainLooper()
)
_isActive.value = true
} catch (e: SecurityException) {
_isActive.value = false
// Handle permission exception
logger("SpeedometerViewModel", "Location permission error: ${e.message}")
}
}
}

/**
* Stops location updates
*/
fun stopLocationUpdates() {
viewModelScope.launch {
fusedLocationClient.removeLocationUpdates(locationCallback)
_isActive.value = false
_speed.value = 0.0f
_accelerationStatus.value = "Stable"
previousSpeed = 0.0f
}
}

override fun onCleared() {
super.onCleared()
if (_isActive.value) {
stopLocationUpdates()
}
}
< /code>
} < /p>
Sammeln Sie diesen StateFlow mit < /p>
    val speed by speedVM.speed.collectAsStateWithLifecycle()

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post