feat: implement two-location speed calculation when native speed unavailable
This commit is contained in:
parent
eca39e542c
commit
c9e49c6cbd
1 changed files with 88 additions and 6 deletions
|
|
@ -13,7 +13,9 @@ import android.net.ConnectivityManager
|
|||
import android.location.Location
|
||||
import android.os.Binder
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.IBinder
|
||||
import android.os.Looper
|
||||
import android.os.PowerManager
|
||||
import androidx.core.app.NotificationCompat
|
||||
import dev.fiatcode.tracpulse.BridgeModule
|
||||
|
|
@ -57,6 +59,9 @@ class LocationTrackingService : Service() {
|
|||
private var bypassFilterOnce = false
|
||||
|
||||
private var currentConfig: TrackingConfig? = null
|
||||
private var pendingSpeedLocation: Location? = null
|
||||
private var speedRequestPending = false
|
||||
private val SPEED_CALC_DELAY_MS = 2500L
|
||||
|
||||
inner class LocalBinder : Binder() {
|
||||
fun getService(): LocationTrackingService = this@LocationTrackingService
|
||||
|
|
@ -143,6 +148,8 @@ class LocationTrackingService : Service() {
|
|||
|
||||
isTracking = true
|
||||
distanceFilterProcessor.reset()
|
||||
pendingSpeedLocation = null
|
||||
speedRequestPending = false
|
||||
prefs.edit().putBoolean("tracking_active", true).apply()
|
||||
Log.d(TAG, "startTracking: set tracking_active=true")
|
||||
|
||||
|
|
@ -226,15 +233,22 @@ class LocationTrackingService : Service() {
|
|||
}
|
||||
bypassFilterOnce = false
|
||||
|
||||
val nativeSpeed = if (location.hasSpeed()) location.speed else null
|
||||
|
||||
if (nativeSpeed == null || nativeSpeed <= 0) {
|
||||
pendingSpeedLocation = location
|
||||
requestLocationForSpeedCalculation()
|
||||
}
|
||||
|
||||
val traccarLocation = TraccarLocation(
|
||||
timestamp = location.time,
|
||||
latitude = location.latitude,
|
||||
longitude = location.longitude,
|
||||
accuracy = if (location.hasAccuracy()) location.accuracy else null,
|
||||
speed = if (location.hasSpeed()) location.speed else null,
|
||||
speed = nativeSpeed,
|
||||
heading = if (location.hasBearing()) location.bearing else null,
|
||||
altitude = if (location.hasAltitude()) location.altitude else null,
|
||||
isMoving = location.speed > 1.0f // Consider moving if speed > 1 m/s
|
||||
isMoving = (nativeSpeed ?: 0f) > 1.0f
|
||||
)
|
||||
|
||||
logEvent("LOCATION", "Lat: ${location.latitude}, Lon: ${location.longitude}, Speed: ${location.speed}")
|
||||
|
|
@ -262,12 +276,14 @@ class LocationTrackingService : Service() {
|
|||
apply()
|
||||
}
|
||||
|
||||
if (nativeSpeed != null && nativeSpeed > 0) {
|
||||
if (isNetworkAvailable) {
|
||||
sendLocationToServer(traccarLocation)
|
||||
} else {
|
||||
bufferLocation(traccarLocation)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onHeartbeat() {
|
||||
logEvent("HEARTBEAT", "Heartbeat fired")
|
||||
|
|
@ -276,6 +292,58 @@ class LocationTrackingService : Service() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun requestLocationForSpeedCalculation() {
|
||||
if (speedRequestPending) return
|
||||
|
||||
speedRequestPending = true
|
||||
Handler(Looper.getMainLooper()).postDelayed({
|
||||
fusedLocationProvider.getLastLocation { location ->
|
||||
location?.let {
|
||||
val calculatedSpeed = distanceFilterProcessor.getCalculatedSpeed(it)
|
||||
onSpeedLocationReceived(it, calculatedSpeed)
|
||||
}
|
||||
speedRequestPending = false
|
||||
pendingSpeedLocation = null
|
||||
}
|
||||
}, SPEED_CALC_DELAY_MS)
|
||||
}
|
||||
|
||||
private fun onSpeedLocationReceived(location: Location, calculatedSpeed: Float?) {
|
||||
val config = currentConfig ?: return
|
||||
|
||||
val finalSpeed = if (location.hasSpeed() && location.speed > 0) {
|
||||
location.speed
|
||||
} else {
|
||||
calculatedSpeed
|
||||
}
|
||||
|
||||
if (finalSpeed == null || finalSpeed <= 0) {
|
||||
logEvent("SPEED_CALC", "Speed calculation failed - insufficient data")
|
||||
return
|
||||
}
|
||||
|
||||
val traccarLocation = TraccarLocation(
|
||||
timestamp = location.time,
|
||||
latitude = location.latitude,
|
||||
longitude = location.longitude,
|
||||
accuracy = if (location.hasAccuracy()) location.accuracy else null,
|
||||
speed = finalSpeed,
|
||||
heading = if (location.hasBearing()) location.bearing else null,
|
||||
altitude = if (location.hasAltitude()) location.altitude else null,
|
||||
isMoving = finalSpeed > 1.0f
|
||||
)
|
||||
|
||||
logEvent("LOCATION", "Lat: ${location.latitude}, Lon: ${location.longitude}, Calc Speed: ${finalSpeed}")
|
||||
|
||||
updateNotificationSpeed(location, finalSpeed)
|
||||
|
||||
if (isNetworkAvailable) {
|
||||
sendLocationToServer(traccarLocation)
|
||||
} else {
|
||||
bufferLocation(traccarLocation)
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendLocationToServer(location: TraccarLocation) {
|
||||
val config = currentConfig ?: return
|
||||
val traccarConfig = TraccarConfig(
|
||||
|
|
@ -407,6 +475,20 @@ class LocationTrackingService : Service() {
|
|||
notificationManager.notify(NOTIFICATION_ID, notification)
|
||||
}
|
||||
|
||||
private fun updateNotificationSpeed(location: Location, speed: Float) {
|
||||
val content = buildString {
|
||||
append("Lat: %.4f Lon: %.4f".format(location.latitude, location.longitude))
|
||||
append("\nSpeed: %.0f km/h (calc)".format(speed * 3.6))
|
||||
val time = java.text.SimpleDateFormat("HH:mm:ss", java.util.Locale.getDefault())
|
||||
.format(java.util.Date(location.time))
|
||||
append("\nLast: $time")
|
||||
}
|
||||
|
||||
val notification = createNotification(content)
|
||||
val notificationManager = getSystemService(NotificationManager::class.java)
|
||||
notificationManager.notify(NOTIFICATION_ID, notification)
|
||||
}
|
||||
|
||||
private fun acquireWakeLock() {
|
||||
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||
wakeLock = powerManager.newWakeLock(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue