this post was submitted on 21 Feb 2024
16 points (90.0% liked)

Android

27554 readers
149 users here now

DROID DOES

Welcome to the droidymcdroidface-iest, Lemmyest (Lemmiest), test, bestest, phoniest, pluckiest, snarkiest, and spiciest Android community on Lemmy (Do not respond)! Here you can participate in amazing discussions and events relating to all things Android.

The rules for posting and commenting, besides the rules defined here for lemmy.world, are as follows:

Rules


1. All posts must be relevant to Android devices/operating system.


2. Posts cannot be illegal or NSFW material.


3. No spam, self promotion, or upvote farming. Sources engaging in these behavior will be added to the Blacklist.


4. Non-whitelisted bots will be banned.


5. Engage respectfully: Harassment, flamebaiting, bad faith engagement, or agenda posting will result in your posts being removed. Excessive violations will result in temporary or permanent ban, depending on severity.


6. Memes are not allowed to be posts, but are allowed in the comments.


7. Posts from clickbait sources are heavily discouraged. Please de-clickbait titles if it needs to be submitted.


8. Submission statements of any length composed of your own thoughts inside the post text field are mandatory for any microblog posts, and are optional but recommended for article/image/video posts.


Community Resources:


We are Android girls*,

In our Lemmy.world.

The back is plastic,

It's fantastic.

*Well, not just girls: people of all gender identities are welcomed here.


Our Partner Communities:

[email protected]


founded 1 year ago
MODERATORS
 

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.


object MyLocationManager {
    val providers = listOf(
        LocationManager.GPS_PROVIDER,
        "fused",
        LocationManager.NETWORK_PROVIDER,
        LocationManager.PASSIVE_PROVIDER,
    )


    fun getCached(ctx: Context, locationManager: LocationManager): Location? {
        for (provider in providers) {
            when (provider) {
                "fused" -> {
                    val fusedLocationClient =
                        LocationServices.getFusedLocationProviderClient(ctx)
                    val fusedLocationTask = fusedLocationClient.lastLocation
                    val fusedLocation = getTaskResult(fusedLocationTask)
                    if (fusedLocation != null) {
                        return fusedLocation
                    }
                }
                else -> {
                    if (locationManager.isProviderEnabled(provider)) {
                        val lastKnownLocation = locationManager.getLastKnownLocation(provider)
                        Log.d(
                            TAG,
                            "Provider: $provider, Last Known Location: $lastKnownLocation"
                        )

                        if (lastKnownLocation != null) {
                            return lastKnownLocation
                        }
                    }
                }
            }
        }

        return null
    }

    fun getLive(ctx: Context, locationManager: LocationManager): Location? {
        val locationListener = object : LocationListener {
            override fun onLocationChanged(location: Location) {

                //This works correctly!
                //
                //1) how to save its result? How to save it into cache?
                //2) or how to return it from here?
                Log.d(TAG, "onLocationChanged: ${location.latitude}, ${location.longitude}")

                stopLocationUpdates()
            }

            private fun stopLocationUpdates() {
                val fusedLocationClient = LocationServices.getFusedLocationProviderClient(ctx)

                try {
                    // Stop location updates
                    fusedLocationClient.removeLocationUpdates(locationCallback)
                    Log.d(TAG, "Location updates stopped")
                } catch (e: SecurityException) {
                    Log.e(TAG, "SecurityException while stopping location updates: ${e.message}")
                }
            }

            private val locationCallback = object : LocationCallback() {
                override fun onLocationResult(locationResult: LocationResult) {
                    super.onLocationResult(locationResult)
                    val location = locationResult.lastLocation
                    if (location != null) {
                        onLocationChanged(location)
                    } else {
                        Log.e(TAG, "Received null location in onLocationResult")
                    }
                }
            }
        }

        for (provider in providers) {
            when (provider) {
                LocationManager.GPS_PROVIDER -> {

                    //obsolete, in the last Android versions
                    val _locationRequest = LocationRequest.create()
                        .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                        .setInterval(0)
                        .setFastestInterval(0)

                    val fusedLocationClient = LocationServices.getFusedLocationProviderClient(ctx)
                    val locationResult: Task = fusedLocationClient.getLocationAvailability()

                    if (!Tasks.await(locationResult).isLocationAvailable) {
                        return null
                    }

                    val locationTask: Task = fusedLocationClient.getCurrentLocation(
                        LocationRequest.PRIORITY_HIGH_ACCURACY,
                        null
                    )

                    return Tasks.await(locationTask)
                }

                "fused" -> {
                    val apiAvailability = GoogleApiAvailability.getInstance()
                    val resultCode = apiAvailability.isGooglePlayServicesAvailable(ctx)

                    if (resultCode == ConnectionResult.SUCCESS) {
                        val fusedLocationClient = LocationServices.getFusedLocationProviderClient(ctx)
                        val fusedLocationTask = fusedLocationClient.lastLocation
                        val fusedLocation = getTaskResult(fusedLocationTask)
                        if (fusedLocation != null) {
                            return fusedLocation
                        }
                    } else {
                        Log.w(TAG, " Google Play Services aren't available, can't use fused")
                    }

                }

                else -> {
                    if (locationManager.isProviderEnabled(provider)) {
                        locationManager.requestSingleUpdate(
                            provider,
                            locationListener,
                            Looper.getMainLooper()
                        )

                        val lastKnownLocation = locationManager.getLastKnownLocation(provider)
                        if (lastKnownLocation != null) {
                            return lastKnownLocation
                        }
                    }
                }
            }
        }

        return null
    }
}


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.

no comments (yet)
sorted by: hot top controversial new old
there doesn't seem to be anything here