Realtime gps optimized for efficiency

This commit is contained in:
wengki81 2025-06-22 00:56:38 +08:00
parent 22c6277d68
commit a7bf869c8e

View File

@ -4,6 +4,8 @@ import android.Manifest
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.Color import android.graphics.Color
import android.os.Build import android.os.Build
import android.os.Handler
import android.os.Looper
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.view.WindowInsetsController import android.view.WindowInsetsController
@ -27,6 +29,7 @@ import com.getcapacitor.annotation.PermissionCallback
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import kotlin.math.* import kotlin.math.*
import android.location.Location
@CapacitorPlugin( @CapacitorPlugin(
name = "DumonGeolocation", name = "DumonGeolocation",
@ -74,6 +77,11 @@ class DumonGeolocation : Plugin() {
private var motionState: String = "idle" // 'idle', 'driving', 'mocked' private var motionState: String = "idle" // 'idle', 'driving', 'mocked'
private var bufferedDrivingLocation: Location? = null
private var drivingEmitHandler: Handler? = null
private var drivingEmitRunnable: Runnable? = null
private val drivingEmitIntervalMs = 1500L
private var currentTrackingMode = GpsTrackingMode.NORMAL private var currentTrackingMode = GpsTrackingMode.NORMAL
override fun load() { override fun load() {
@ -92,7 +100,12 @@ class DumonGeolocation : Plugin() {
latestSource = if (isMocked) "MOCK" else "GNSS" latestSource = if (isMocked) "MOCK" else "GNSS"
isMockedLocation = isMocked isMockedLocation = isMocked
latestTimestamp = location.time latestTimestamp = location.time
emitPositionUpdate()
if (currentTrackingMode == GpsTrackingMode.DRIVING) {
bufferedDrivingLocation = location
} else {
emitPositionUpdate() // langsung emit di mode normal
}
} }
) )
@ -114,6 +127,33 @@ class DumonGeolocation : Plugin() {
) )
} }
private fun startDrivingEmitLoop() {
if (drivingEmitHandler != null) return // already running
drivingEmitHandler = Handler(Looper.getMainLooper())
drivingEmitRunnable = object : Runnable {
override fun run() {
bufferedDrivingLocation?.let { location ->
latestLatitude = location.latitude
latestLongitude = location.longitude
latestAccuracy = location.accuracy.toDouble()
latestTimestamp = location.time
latestSource = if (isMockedLocation) "MOCK" else "GNSS"
emitPositionUpdate()
}
drivingEmitHandler?.postDelayed(this, drivingEmitIntervalMs)
}
}
drivingEmitHandler?.postDelayed(drivingEmitRunnable!!, drivingEmitIntervalMs)
}
private fun stopDrivingEmitLoop() {
drivingEmitHandler?.removeCallbacks(drivingEmitRunnable!!)
drivingEmitHandler = null
drivingEmitRunnable = null
bufferedDrivingLocation = null
}
@PluginMethod @PluginMethod
fun startPositioning(call: PluginCall) { fun startPositioning(call: PluginCall) {
if (!PermissionUtils.hasLocationAndWifiPermissions(context)) { if (!PermissionUtils.hasLocationAndWifiPermissions(context)) {
@ -132,6 +172,7 @@ class DumonGeolocation : Plugin() {
gpsManager?.stop() gpsManager?.stop()
imuManager?.stop() imuManager?.stop()
wifiManager?.stopPeriodicScan() wifiManager?.stopPeriodicScan()
stopDrivingEmitLoop()
call.resolve() call.resolve()
} }
@ -229,9 +270,13 @@ class DumonGeolocation : Plugin() {
val mode = call.getString("mode") ?: "normal" val mode = call.getString("mode") ?: "normal"
if (mode == "driving") { if (mode == "driving") {
gpsManager?.startContinuousMode() gpsManager?.startContinuousMode()
currentTrackingMode = GpsTrackingMode.DRIVING
startDrivingEmitLoop()
Log.d("DUMON_GEOLOCATION", "Switched to driving mode (continuous GPS)") Log.d("DUMON_GEOLOCATION", "Switched to driving mode (continuous GPS)")
} else { } else {
gpsManager?.startPollingMode() gpsManager?.startPollingMode()
currentTrackingMode = GpsTrackingMode.NORMAL
stopDrivingEmitLoop()
Log.d("DUMON_GEOLOCATION", "Switched to normal mode (polling GPS)") Log.d("DUMON_GEOLOCATION", "Switched to normal mode (polling GPS)")
} }
call.resolve() call.resolve()