0

I'm trying to make an android google maps app and I'm having trouble with the global variables I assign values to inside the listener not being completed. In this case, I'm trying to store the current location of the device after setting a marker there, and the documentation said to use a listener. The problem is, the values reset to their previous values after the listener is complete, and I can't return from inside the listener.

Here's the variable, it's not private right now because I was testing if it affected it for some reason:

lateinit var latLng : LatLng

Here's the function causing the problems:

private fun setDestinations() : LatLng{
    checkPermission()
    var locationResult = fusedLocationProviderClient.lastLocation;
    var lat = 0.0
    var lng = 0.0
        locationResult.addOnCompleteListener(this) { task ->
            if(task.isSuccessful){
                lng = locationResult.result.longitude
                lat = locationResult.result.latitude
                latLng = LatLng(lat, lng)
                setBaseLocation(lat, lng)
                /**debug**/
                println("First: $lat $lng")
            } else {
                Toast.makeText(this, "Cannot retrieve location", Toast.LENGTH_LONG).show()
            }
        }
    println("Third: " + latLng.latitude + " " +  latLng.latitude)
    return latLng
}

I get thrown an error when it reaches return saying that latLng has not been initialized

please help me if you can, I really need it

Chulainn
  • 1
  • 1
  • `addOnCompleteListener` is a async call . and you are accessing the variable outside the block synchronously . Also you can not return value this way . better use some observer mechanism maybe `LiveData` or a Observable Field . – ADM Apr 26 '22 at 05:33

3 Answers3

1

In your code locationResult.addOnCompleteListener(this) { task -> } is an async callback and it will return the result once the async task (fetching the location) is done. Meanwhile your rest of the code outside this callback is called synchronously, So it returns the latlng while the addOnCompleteListener callback is still waiting for a result. That causes the "latLng has not been initialized"

More about synchronous and asynchronous executions : Asynchronous vs synchronous execution, what is the main difference?

Naresh NK
  • 1,036
  • 1
  • 9
  • 16
0

you sure this line println("Third: " + latLng.latitude + " " + latLng.latitude) is not throwing the error?

Cause this line also using latLng.

As of an asynchronous callback,the latLng is not initialized before the synchronous return is executed. And that's why you should get error in the print line.

0

That's because this part is not called when the function returns.

locationResult.addOnCompleteListener(this) { task ->
    if(task.isSuccessful){
       lng = locationResult.result.longitude
       lat = locationResult.result.latitude
       latLng = LatLng(lat, lng)
       setBaseLocation(lat, lng)
       
       /**debug**/
       println("First: $lat $lng")
    } else {
        Toast.makeText(this, "Cannot retrieve location", Toast.LENGTH_LONG).show()
    }
}

So, your method is like

private fun setDestinations() : LatLng{
    checkPermission()
    return latLng
}

You should avoid return or you need to make sure if the variable is initialized before it returns. You need to make it syncronized.

c-an
  • 3,543
  • 5
  • 35
  • 82