fusedLocationProviderClient.lastLocation.addOnSuccessListener always null

11,599

Solution 1

I found a solution, this is what happens, when the location is null it means the location cache was cleared, this happens when turning off GPS, so when I was turning it on there was no last location to get, what I did was this:

checkLocationSettings(callingActivity, turnOnGpsRequestCode, callback) {
                // Location settings successful
                mFusedLocationProviderClient!!.lastLocation
                        .addOnSuccessListener(callingActivity) {
                            location ->
                            if (location == null || location.accuracy > 100) {
                                mLocationCallback = object : LocationCallback() {
                                    override fun onLocationResult(locationResult: LocationResult?) {
                                        stopLocationUpdates()
                                        if (locationResult != null && locationResult.locations.isNotEmpty()) {
                                            val newLocation = locationResult.locations[0]
                                            callback.onCallback(Status.SUCCESS, newLocation)
                                        } else {
                                            callback.onCallback(Status.ERROR_LOCATION, null)
                                        }
                                    }
                                }

                                mFusedLocationProviderClient!!.requestLocationUpdates(getLocationRequest(),
                                        mLocationCallback, null)
                            } else {
                                callback.onCallback(Status.SUCCESS, location)
                            }
                        }
                        .addOnFailureListener {
                            callback.onCallback(Status.ERROR_UNKNOWN, null)
                        }
            }

When the location is null, start requesting locations using a callback and

mFusedLocationProviderClient!!.requestLocationUpdates(getLocationRequest(), mLocationCallback, null)

Then when the callback is called, a new location is got and it starts getting location again.

Sometimes it happens that when you turn on the GPS, the location is not null but the accuracy is bad, so I also check if location accuracy is good enough (For me good enough is 100 meters)

Solution 2

You can use getLocationAvailability() method on your FusedLocationPrivedClient object and if it returns true then only use getLastLocation() method otherwise use requestLocationUpdates() method like this :

FusedLocationProviderClient fusedLocationProviderClient =
            LocationServices.getFusedLocationProviderClient(InitActivity.this);
    if (ActivityCompat.checkSelfPermission(this.getApplicationContext(),
            android.Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {

fusedLocationProviderClient.getLocationAvailability().addOnSuccessListener(new OnSuccessListener<LocationAvailability>() {
                @Override
                public void onSuccess(LocationAvailability locationAvailability) {
                    Log.d(TAG, "onSuccess: locationAvailability.isLocationAvailable " + locationAvailability.isLocationAvailable());
                    if (locationAvailability.isLocationAvailable()) {
                        if (ActivityCompat.checkSelfPermission(InitActivity.this.getApplicationContext(),
                                android.Manifest.permission.ACCESS_FINE_LOCATION)
                                == PackageManager.PERMISSION_GRANTED) {
                            Task<Location> locationTask = fusedLocationProviderClient.getLastLocation();
                            locationTask.addOnCompleteListener(new OnCompleteListener<Location>() {
                                @Override
                                public void onComplete(@NonNull Task<Location> task) {
                                    Location location = task.getResult();                                    
                                }
                            });
                        } else {
                            requestLocationPermissions ();
                        }

                    } else {
fusedLocationProviderClient.requestLocationUpdates(locationRequest, pendingIntent);

                    }

                }
            });
        } else {
            requestLocationPermissions ();
        }
Share:
11,599
Jesus Almaral - Hackaprende
Author by

Jesus Almaral - Hackaprende

I am a mobile (mostly Android) developer who loves coding, I like to work for challenging startups who are crossing beyond the technologic limits. I have several programming courses on Udemy (Sorry, only in spanish :/), I also have a blog, which I use mainly as a hobby to teach what I know and my experiences as developer (You can find me as Hackaprende) As for my academic background, I am Mechatronics engineer and have a Master degree on Machine Learning and image processing. It would be great to combine these skills with mobile programming!

Updated on July 08, 2022

Comments

  • Jesus Almaral - Hackaprende
    Jesus Almaral - Hackaprende almost 2 years

    I just updated my Location API to use FusedLocationProviderClient but I am having this issue, when I turn off and on the GPS, I am always getting null location:

    val fusedLocationProviderClient =
                            LocationServices.getFusedLocationProviderClient(callingActivity)
                fusedLocationProviderClient.flushLocations()
                getLocationRequest()
    
                checkLocationSettings(callingActivity, turnOnGpsRequestCode, callback) {
                    // Location settings successful
                    fusedLocationProviderClient.lastLocation
                            .addOnSuccessListener(callingActivity) {
                                location ->
                                // Here location is always null
    callback.onCallback(MenumyRadar.RadarStatus.SUCCESS, location)
                            }
                            .addOnFailureListener {
                                callback.onCallback(MenumyRadar.RadarStatus.ERROR_UNKNOWN, null)
                            }
                }
    

    It doesn´t work until I open another app which uses location, as Google Maps or Uber.

    I have some clue thanks to this answer FusedLocationApi.getLastLocation always null

    And to Google´s explanation:

    fusedLocationClient.lastLocation .addOnSuccessListener { location : Location? -> // Got last known location. In some rare situations this can be null. }

    The getLastLocation() method returns a Task that you can use to get a Location object with the latitude and longitude coordinates of a geographic location. The location object may be null in the following situations:

    Location is turned off in the device settings. The result could be null even if the last location was previously retrieved because disabling location also clears the cache. The device never recorded its location, which could be the case of a new device or a device that has been restored to factory settings. Google Play services on the device has restarted, and there is no active Fused Location Provider client that has requested location after the services restarted. To avoid this situation you can create a new client and request location updates yourself. For more information, see Receiving Location Updates.

    But it does not say how to handle this, what can I do?

  • CoolMind
    CoolMind over 3 years
    Doesn't work on fresh emulator API 19 with turned on GPS. onLocationResult is not called.
  • CoolMind
    CoolMind over 3 years
    What is pendingIntent? locationAvailability?.isLocationAvailable == false in fresh API 19 emulator.