Realtime gps optimized for efficiency
This commit is contained in:
parent
8bcd143854
commit
10c64ce5d1
@ -284,6 +284,7 @@ class DumonGeolocation : Plugin() {
|
|||||||
|
|
||||||
if (emitIntervalMs != targetInterval) {
|
if (emitIntervalMs != targetInterval) {
|
||||||
emitIntervalMs = targetInterval
|
emitIntervalMs = targetInterval
|
||||||
|
gpsManager?.setPollingInterval(targetInterval)
|
||||||
Log.d("DUMON_GEOLOCATION", "Auto-set emitIntervalMs = $emitIntervalMs ms")
|
Log.d("DUMON_GEOLOCATION", "Auto-set emitIntervalMs = $emitIntervalMs ms")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,8 @@ import android.location.LocationListener
|
|||||||
import android.location.LocationManager
|
import android.location.LocationManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
import android.text.format.DateFormat
|
import android.text.format.DateFormat
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
@ -20,6 +22,9 @@ class GpsStatusManager(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
private val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
private val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||||
|
private val handler = Handler(Looper.getMainLooper())
|
||||||
|
private var pollingIntervalMs: Long = 1000L // default 1 second
|
||||||
|
private var isPolling = false
|
||||||
|
|
||||||
private val gnssStatusCallback = object : GnssStatus.Callback() {
|
private val gnssStatusCallback = object : GnssStatus.Callback() {
|
||||||
override fun onSatelliteStatusChanged(status: GnssStatus) {
|
override fun onSatelliteStatusChanged(status: GnssStatus) {
|
||||||
@ -43,7 +48,8 @@ class GpsStatusManager(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val locationListener = object : LocationListener {
|
private fun pollOnceAndEmit() {
|
||||||
|
val oneShotListener = object : LocationListener {
|
||||||
override fun onLocationChanged(location: Location) {
|
override fun onLocationChanged(location: Location) {
|
||||||
val providerTag = when (location.provider) {
|
val providerTag = when (location.provider) {
|
||||||
LocationManager.GPS_PROVIDER -> "[GPS]"
|
LocationManager.GPS_PROVIDER -> "[GPS]"
|
||||||
@ -62,20 +68,43 @@ class GpsStatusManager(
|
|||||||
Log.d("GPS_LOCATION", info)
|
Log.d("GPS_LOCATION", info)
|
||||||
|
|
||||||
onLocationUpdate(location, isMocked)
|
onLocationUpdate(location, isMocked)
|
||||||
|
|
||||||
|
locationManager.removeUpdates(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Deprecated in Java")
|
|
||||||
override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {}
|
override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {}
|
||||||
|
|
||||||
override fun onProviderEnabled(provider: String) {}
|
override fun onProviderEnabled(provider: String) {}
|
||||||
override fun onProviderDisabled(provider: String) {}
|
override fun onProviderDisabled(provider: String) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
locationManager.requestLocationUpdates(
|
||||||
|
LocationManager.GPS_PROVIDER,
|
||||||
|
0L,
|
||||||
|
0f,
|
||||||
|
oneShotListener
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Log.e("GPS_STATUS", "Missing location permission")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val pollingRunnable = object : Runnable {
|
||||||
|
override fun run() {
|
||||||
|
if (!isPolling) return
|
||||||
|
pollOnceAndEmit()
|
||||||
|
handler.postDelayed(this, pollingIntervalMs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setPollingInterval(intervalMs: Long) {
|
||||||
|
this.pollingIntervalMs = intervalMs
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
fun start() {
|
fun start() {
|
||||||
try {
|
try {
|
||||||
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
|
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||||
ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
Log.e("GPS_STATUS", "Missing location permissions")
|
Log.e("GPS_STATUS", "Missing location permissions")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -88,48 +117,32 @@ class GpsStatusManager(
|
|||||||
}
|
}
|
||||||
|
|
||||||
locationManager.registerGnssStatusCallback(gnssStatusCallback, null)
|
locationManager.registerGnssStatusCallback(gnssStatusCallback, null)
|
||||||
|
isPolling = true
|
||||||
|
handler.post(pollingRunnable)
|
||||||
|
|
||||||
locationManager.requestLocationUpdates(
|
// Fallback lokasi terakhir
|
||||||
LocationManager.GPS_PROVIDER,
|
|
||||||
0L,
|
|
||||||
0f,
|
|
||||||
locationListener
|
|
||||||
)
|
|
||||||
|
|
||||||
locationManager.requestLocationUpdates(
|
|
||||||
LocationManager.NETWORK_PROVIDER,
|
|
||||||
3000L,
|
|
||||||
10f,
|
|
||||||
locationListener
|
|
||||||
)
|
|
||||||
|
|
||||||
Log.d("GPS_STATUS", "GPS + Network location tracking started")
|
|
||||||
|
|
||||||
// 🔥 Fallback: coba ambil lokasi terakhir
|
|
||||||
val lastKnown = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
|
val lastKnown = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
|
||||||
?: locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
|
?: locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
|
||||||
|
|
||||||
lastKnown?.let { location ->
|
lastKnown?.let { location ->
|
||||||
if (location.latitude != 0.0 && location.longitude != 0.0) {
|
if (location.latitude != 0.0 && location.longitude != 0.0) {
|
||||||
val isMocked = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
val isMocked = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) location.isMock else location.isFromMockProvider
|
||||||
location.isMock
|
|
||||||
} else {
|
|
||||||
location.isFromMockProvider
|
|
||||||
}
|
|
||||||
Log.d("GPS_STATUS", "Using last known location as fallback")
|
Log.d("GPS_STATUS", "Using last known location as fallback")
|
||||||
onLocationUpdate(location, isMocked)
|
onLocationUpdate(location, isMocked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.d("GPS_STATUS", "One-shot GPS polling started")
|
||||||
} catch (e: SecurityException) {
|
} catch (e: SecurityException) {
|
||||||
Log.e("GPS_STATUS", "SecurityException", e)
|
Log.e("GPS_STATUS", "SecurityException", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stop() {
|
fun stop() {
|
||||||
|
isPolling = false
|
||||||
|
handler.removeCallbacks(pollingRunnable)
|
||||||
locationManager.unregisterGnssStatusCallback(gnssStatusCallback)
|
locationManager.unregisterGnssStatusCallback(gnssStatusCallback)
|
||||||
locationManager.removeUpdates(locationListener)
|
Log.d("GPS_STATUS", "GPS polling stopped")
|
||||||
Log.d("GPS_STATUS", "GPS tracking stopped")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getConstellationName(type: Int): String {
|
private fun getConstellationName(type: Int): String {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user