OSMDroid LocationChange Listener

Viewed 170

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)

    }
1 Answers

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)
    }
Related