androidlocationheremapsheremaps-android-sdk

What is the Faster way to track users current location periodically?


I have finished the product I was developing, but currently, we track the users ( passenger ) location as well as the drivers too slowly. This is the code I use to track and update the map with the passangers/ drivers icon as it moves :

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.location.Location
import android.os.Looper
import android.util.Log
import androidx.core.content.ContextCompat
import com.google.android.gms.location.*
import mobi.audax.tupi.motorista.bin.task.GeoDecodeTask
import mobi.audax.tupi.passageiro.util.Prefs


class IntermitentLocationThread(val context: Context, val onLocationUpdate: (location: Location?) -> Unit) : LocationListener {

    private var UPDATE_INTERVAL = (1000 * 10).toLong()  // 10 segundos de intervalo
    private val MAX_WAIT_TIME = UPDATE_INTERVAL * 2  // 20 segundos
    private var bestLocation: Location? = null

    fun requestLocation() {
        this.locationService()
    }

    private fun locationService() {
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            val locationRequest = LocationRequest.create()
            locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
            locationRequest.fastestInterval = 1000
            locationRequest.interval = UPDATE_INTERVAL
            locationRequest.maxWaitTime = MAX_WAIT_TIME
            locationRequest.smallestDisplacement = 15f
            val fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context)
            fusedLocationProviderClient.lastLocation.addOnSuccessListener { location -> onLocationChanged(location) }
            fusedLocationProviderClient.requestLocationUpdates(locationRequest, object : LocationCallback() {
                override fun onLocationResult(locationResult: LocationResult) {
                    onLocationChanged(locationResult.lastLocation)
                }
            }, Looper.myLooper()!!)
        }
    }

    override fun onLocationChanged(location: Location) {
        try {
            Log.v("IntermitentLocationThread", "onLocationChanged")
            if (location != null) {
                val commons = LocationCommons()
//                if (!commons.isMock(context, location) && commons.isBetterLocation(location, bestLocation)) {
                Log.v("IntermitentLocationThread", "isBetter true")
                val prefs = Prefs(context)
                prefs.latitude = location.latitude.toFloat()
                prefs.longitude = location.longitude.toFloat()
                prefs.precisao = location.accuracy
                prefs.velocidade = location.speed * 3.6f
                prefs.bearing = location.bearing
                if (location.extras.containsKey("satellites")) {
                    prefs.satellites = location.extras.getInt("satellites")
                }

                GeoDecodeTask(context, location).decoder { }
                bestLocation = location

                onLocationUpdate(bestLocation)
                } else {
                    Log.v("IntermitentLocationThread", "isBetter false")
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

}

and heres how i implement it in my Activity:

private void handleLocationUpdates() {

        if (isLocationEnabled()) {
            loadMapScene();
            IntermitentLocationThread thread = new IntermitentLocationThread(this, location -> {
                Log.e(TAG, "handleLocationUpdates: "+"pegado localização" );
                clearPassageiroMapMarker();
                addPassageiroMarker(new GeoCoordinates(location.getLatitude(), 
                location.getLongitude()), R.drawable.ic_passageiro);

                passageiro.setLat(location.getLatitude());
                passageiro.setLongitude(location.getLongitude());
                SharedPreferences.Editor editor = this.getSharedPreferences(Constantss.PREFERENCES, MODE_PRIVATE).edit();
                mapView.getCamera().lookAt(new GeoCoordinates(passageiro.getLat(), passageiro.getLongitude()));

         
                return null;
            });
            thread.requestLocation();


        } else {
            Toast.makeText(this, "Por favor" + "ative sua localização...", Toast.LENGTH_LONG).show();
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);
        }
    }

at the moment, I get passengers/drivers' locations in a very weird and odd consistency, it's not as " fluid " as uber does it. right now, my marker jumps from one point to another (because I clear the marker list and set another one in place, still working on having only one marker in a heremaps map) in a range of 5 to 15 seconds and everybody else on the internet seems to use this google engine to track one's location.

How is it possible to track users' location in a faster / smoother way?


Solution

  • i was able to find a better/fast tracking by using Google's Location Manager... yes.. LocationManager. The code i was using before that wasnt really accurate at all, with Googles Location Manager i was able to set a specific timer and keep it accurate. More on : https://developer.android.com/reference/android/location/LocationManager