How to obtain a) cached b) live GPS location properly? What's the right approach?

I have an app which polls a remote server by sending to it its cache GPS location. Sometimes a remote server will ask for live location and an app must send it to it.



<span style="color:#323232;">object MyLocationManager {
</span><span style="color:#323232;">    val providers = listOf(
</span><span style="color:#323232;">        LocationManager.GPS_PROVIDER,
</span><span style="color:#323232;">        "fused",
</span><span style="color:#323232;">        LocationManager.NETWORK_PROVIDER,
</span><span style="color:#323232;">        LocationManager.PASSIVE_PROVIDER,
</span><span style="color:#323232;">    )
</span><span style="color:#323232;">
</span><span style="color:#323232;">
</span><span style="color:#323232;">    fun getCached(ctx: Context, locationManager: LocationManager): Location? {
</span><span style="color:#323232;">        for (provider in providers) {
</span><span style="color:#323232;">            when (provider) {
</span><span style="color:#323232;">                "fused" -> {
</span><span style="color:#323232;">                    val fusedLocationClient =
</span><span style="color:#323232;">                        LocationServices.getFusedLocationProviderClient(ctx)
</span><span style="color:#323232;">                    val fusedLocationTask = fusedLocationClient.lastLocation
</span><span style="color:#323232;">                    val fusedLocation = getTaskResult(fusedLocationTask)
</span><span style="color:#323232;">                    if (fusedLocation != null) {
</span><span style="color:#323232;">                        return fusedLocation
</span><span style="color:#323232;">                    }
</span><span style="color:#323232;">                }
</span><span style="color:#323232;">                else -> {
</span><span style="color:#323232;">                    if (locationManager.isProviderEnabled(provider)) {
</span><span style="color:#323232;">                        val lastKnownLocation = locationManager.getLastKnownLocation(provider)
</span><span style="color:#323232;">                        Log.d(
</span><span style="color:#323232;">                            TAG,
</span><span style="color:#323232;">                            "Provider: $provider, Last Known Location: $lastKnownLocation"
</span><span style="color:#323232;">                        )
</span><span style="color:#323232;">
</span><span style="color:#323232;">                        if (lastKnownLocation != null) {
</span><span style="color:#323232;">                            return lastKnownLocation
</span><span style="color:#323232;">                        }
</span><span style="color:#323232;">                    }
</span><span style="color:#323232;">                }
</span><span style="color:#323232;">            }
</span><span style="color:#323232;">        }
</span><span style="color:#323232;">
</span><span style="color:#323232;">        return null
</span><span style="color:#323232;">    }
</span><span style="color:#323232;">
</span><span style="color:#323232;">    fun getLive(ctx: Context, locationManager: LocationManager): Location? {
</span><span style="color:#323232;">        val locationListener = object : LocationListener {
</span><span style="color:#323232;">            override fun onLocationChanged(location: Location) {
</span><span style="color:#323232;">
</span><span style="color:#323232;">                //This works correctly!
</span><span style="color:#323232;">                //
</span><span style="color:#323232;">                //1) how to save its result? How to save it into cache?
</span><span style="color:#323232;">                //2) or how to return it from here?
</span><span style="color:#323232;">                Log.d(TAG, "onLocationChanged: ${location.latitude}, ${location.longitude}")
</span><span style="color:#323232;">
</span><span style="color:#323232;">                stopLocationUpdates()
</span><span style="color:#323232;">            }
</span><span style="color:#323232;">
</span><span style="color:#323232;">            private fun stopLocationUpdates() {
</span><span style="color:#323232;">                val fusedLocationClient = LocationServices.getFusedLocationProviderClient(ctx)
</span><span style="color:#323232;">
</span><span style="color:#323232;">                try {
</span><span style="color:#323232;">                    // Stop location updates
</span><span style="color:#323232;">                    fusedLocationClient.removeLocationUpdates(locationCallback)
</span><span style="color:#323232;">                    Log.d(TAG, "Location updates stopped")
</span><span style="color:#323232;">                } catch (e: SecurityException) {
</span><span style="color:#323232;">                    Log.e(TAG, "SecurityException while stopping location updates: ${e.message}")
</span><span style="color:#323232;">                }
</span><span style="color:#323232;">            }
</span><span style="color:#323232;">
</span><span style="color:#323232;">            private val locationCallback = object : LocationCallback() {
</span><span style="color:#323232;">                override fun onLocationResult(locationResult: LocationResult) {
</span><span style="color:#323232;">                    super.onLocationResult(locationResult)
</span><span style="color:#323232;">                    val location = locationResult.lastLocation
</span><span style="color:#323232;">                    if (location != null) {
</span><span style="color:#323232;">                        onLocationChanged(location)
</span><span style="color:#323232;">                    } else {
</span><span style="color:#323232;">                        Log.e(TAG, "Received null location in onLocationResult")
</span><span style="color:#323232;">                    }
</span><span style="color:#323232;">                }
</span><span style="color:#323232;">            }
</span><span style="color:#323232;">        }
</span><span style="color:#323232;">
</span><span style="color:#323232;">        for (provider in providers) {
</span><span style="color:#323232;">            when (provider) {
</span><span style="color:#323232;">                LocationManager.GPS_PROVIDER -> {
</span><span style="color:#323232;">
</span><span style="color:#323232;">                    //obsolete, in the last Android versions
</span><span style="color:#323232;">                    val _locationRequest = LocationRequest.create()
</span><span style="color:#323232;">                        .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
</span><span style="color:#323232;">                        .setInterval(0)
</span><span style="color:#323232;">                        .setFastestInterval(0)
</span><span style="color:#323232;">
</span><span style="color:#323232;">                    val fusedLocationClient = LocationServices.getFusedLocationProviderClient(ctx)
</span><span style="color:#323232;">                    val locationResult: Task = fusedLocationClient.getLocationAvailability()
</span><span style="color:#323232;">
</span><span style="color:#323232;">                    if (!Tasks.await(locationResult).isLocationAvailable) {
</span><span style="color:#323232;">                        return null
</span><span style="color:#323232;">                    }
</span><span style="color:#323232;">
</span><span style="color:#323232;">                    val locationTask: Task = fusedLocationClient.getCurrentLocation(
</span><span style="color:#323232;">                        LocationRequest.PRIORITY_HIGH_ACCURACY,
</span><span style="color:#323232;">                        null
</span><span style="color:#323232;">                    )
</span><span style="color:#323232;">
</span><span style="color:#323232;">                    return Tasks.await(locationTask)
</span><span style="color:#323232;">                }
</span><span style="color:#323232;">
</span><span style="color:#323232;">                "fused" -> {
</span><span style="color:#323232;">                    val apiAvailability = GoogleApiAvailability.getInstance()
</span><span style="color:#323232;">                    val resultCode = apiAvailability.isGooglePlayServicesAvailable(ctx)
</span><span style="color:#323232;">
</span><span style="color:#323232;">                    if (resultCode == ConnectionResult.SUCCESS) {
</span><span style="color:#323232;">                        val fusedLocationClient = LocationServices.getFusedLocationProviderClient(ctx)
</span><span style="color:#323232;">                        val fusedLocationTask = fusedLocationClient.lastLocation
</span><span style="color:#323232;">                        val fusedLocation = getTaskResult(fusedLocationTask)
</span><span style="color:#323232;">                        if (fusedLocation != null) {
</span><span style="color:#323232;">                            return fusedLocation
</span><span style="color:#323232;">                        }
</span><span style="color:#323232;">                    } else {
</span><span style="color:#323232;">                        Log.w(TAG, " Google Play Services aren't available, can't use fused")
</span><span style="color:#323232;">                    }
</span><span style="color:#323232;">
</span><span style="color:#323232;">                }
</span><span style="color:#323232;">
</span><span style="color:#323232;">                else -> {
</span><span style="color:#323232;">                    if (locationManager.isProviderEnabled(provider)) {
</span><span style="color:#323232;">                        locationManager.requestSingleUpdate(
</span><span style="color:#323232;">                            provider,
</span><span style="color:#323232;">                            locationListener,
</span><span style="color:#323232;">                            Looper.getMainLooper()
</span><span style="color:#323232;">                        )
</span><span style="color:#323232;">
</span><span style="color:#323232;">                        val lastKnownLocation = locationManager.getLastKnownLocation(provider)
</span><span style="color:#323232;">                        if (lastKnownLocation != null) {
</span><span style="color:#323232;">                            return lastKnownLocation
</span><span style="color:#323232;">                        }
</span><span style="color:#323232;">                    }
</span><span style="color:#323232;">                }
</span><span style="color:#323232;">            }
</span><span style="color:#323232;">        }
</span><span style="color:#323232;">
</span><span style="color:#323232;">        return null
</span><span style="color:#323232;">    }
</span><span style="color:#323232;">}
</span><span style="color:#323232;">
</span>

An issue is that the code for obtaining GPS location doesn’t work properly. Firstly, I don’t know whether the approach in the code is correct. Secondly, I don’t know how to properly to return the GPS coordinates from a callback – see the comments. Thirdly, I don’t know how to force it to store the latest coordinates that it’s obtained into cache.

And there’re some functions that’s been derprecated in the latest versions of Android, particularly in Android 10.

How to do all of this?

My device is rooted.

  • All
  • Subscribed
  • Moderated
  • Favorites
  • android@lemmy.world
  • Durango
  • DreamBathrooms
  • InstantRegret
  • tacticalgear
  • magazineikmin
  • Youngstown
  • thenastyranch
  • mdbf
  • slotface
  • rosin
  • Leos
  • kavyap
  • modclub
  • ethstaker
  • JUstTest
  • everett
  • GTA5RPClips
  • cubers
  • khanakhh
  • ngwrru68w68
  • anitta
  • provamag3
  • cisconetworking
  • tester
  • osvaldo12
  • megavids
  • normalnudes
  • lostlight
  • All magazines