I'm creating a map and I have a locationOverlay that works fine. However I need to update some variables as the location changes. Do I use a LocationListener with OSMDroid? Or is there something builtin or a method I can override? If I do have to register a locationListener, how do I go about that?
private fun createMap() {
val ctx = applicationContext
Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx))
map = findViewById<View>(R.id.map) as MapView
map.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE)
map.getOverlays().add(CopyrightOverlay(this))
mapController = MapController(map)
mLocationOverlay = MyLocationNewOverlay(GpsMyLocationProvider(this), map)
mLocationOverlay.enableMyLocation()
mLocationOverlay.runOnFirstFix {
runOnUiThread {
mapController.zoomTo(14)
mapController.setCenter(mLocationOverlay.myLocation)
mapController.animateTo(mLocationOverlay.myLocation)
}
}
map.overlays.add(mLocationOverlay)
}
I found that your last known location is stored in the LocationOverlay. To access those variables: mLocationOverlay.myLocationProvider.lastKnownLocation.latitude
and the same for longitude.
Now that I knew where to get my location it was as simple as creating coroutines job to run ever second and update the deviceLocation variable.
I'm sure there might be a better way by registering a listener. It would only fire when the location changes. However with coroutines you can control the interval. Giving the UI a more predictable look as long as the interval isn't too short.
Make sure you have implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0'
in your dependencies
private fun createMap() {
val ctx = applicationContext
Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx))
map = findViewById<View>(R.id.map) as MapView
map.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE)
map.getOverlays().add(CopyrightOverlay(this))
mapController = MapController(map)
mapController.animateTo(GeoPoint(DEFAULT_GEOPOINT), DEFAULT_ZOOM, 2)
mLocationOverlay = MyLocationNewOverlay(GpsMyLocationProvider(this), map)
mLocationOverlay.enableMyLocation()
mLocationOverlay.runOnFirstFix {
runOnUiThread {
mapController.animateTo(mLocationOverlay.myLocation, 14.0, 1000)
handleNewLocation()
startLocationUpdates() // <-----Entry Point
}
}
map.overlays.add(mLocationOverlay)
}
private fun startLocationUpdates() {
val updateDeviceLocationJob = locationUpdateJob(1000L)
updateDeviceLocationJob.start()
}
private fun locationUpdateJob(timeInterval: Long): Job {
return CoroutineScope(Dispatchers.Default).launch {
while (isActive) {
handleNewLocation()
delay(timeInterval)
}
}
}
private fun handleNewLocation() {
deviceGoePoint = LatLng(mLocationOverlay.myLocationProvider.lastKnownLocation.latitude,
mLocationOverlay.myLocationProvider.lastKnownLocation.longitude)
}