From a7bf869c8ed9e1560a28ea04010abc7d0786d8cf Mon Sep 17 00:00:00 2001 From: wengki81 Date: Sun, 22 Jun 2025 00:56:38 +0800 Subject: [PATCH] Realtime gps optimized for efficiency --- .../plugin/geolocation/DumonGeolocation.kt | 47 ++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/com/dumon/plugin/geolocation/DumonGeolocation.kt b/android/src/main/java/com/dumon/plugin/geolocation/DumonGeolocation.kt index 94d6dca..ab016c9 100644 --- a/android/src/main/java/com/dumon/plugin/geolocation/DumonGeolocation.kt +++ b/android/src/main/java/com/dumon/plugin/geolocation/DumonGeolocation.kt @@ -4,6 +4,8 @@ import android.Manifest import android.content.pm.PackageManager import android.graphics.Color import android.os.Build +import android.os.Handler +import android.os.Looper import android.util.Log import android.view.View import android.view.WindowInsetsController @@ -27,6 +29,7 @@ import com.getcapacitor.annotation.PermissionCallback import org.json.JSONArray import org.json.JSONObject import kotlin.math.* +import android.location.Location @CapacitorPlugin( name = "DumonGeolocation", @@ -74,6 +77,11 @@ class DumonGeolocation : Plugin() { 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 override fun load() { @@ -92,7 +100,12 @@ class DumonGeolocation : Plugin() { latestSource = if (isMocked) "MOCK" else "GNSS" isMockedLocation = isMocked 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 fun startPositioning(call: PluginCall) { if (!PermissionUtils.hasLocationAndWifiPermissions(context)) { @@ -132,6 +172,7 @@ class DumonGeolocation : Plugin() { gpsManager?.stop() imuManager?.stop() wifiManager?.stopPeriodicScan() + stopDrivingEmitLoop() call.resolve() } @@ -229,9 +270,13 @@ class DumonGeolocation : Plugin() { val mode = call.getString("mode") ?: "normal" if (mode == "driving") { gpsManager?.startContinuousMode() + currentTrackingMode = GpsTrackingMode.DRIVING + startDrivingEmitLoop() Log.d("DUMON_GEOLOCATION", "Switched to driving mode (continuous GPS)") } else { gpsManager?.startPollingMode() + currentTrackingMode = GpsTrackingMode.NORMAL + stopDrivingEmitLoop() Log.d("DUMON_GEOLOCATION", "Switched to normal mode (polling GPS)") } call.resolve()