The fused Location Provider will only maintain background location if at least one client is connected to it. Now just turning on the location service will not guarantee to store the last known location.

Once the first client connects, it will immediately try to get a location. If your activity is the first client to connect and getLastLocation() is invoked right away in onConnected(), that might not be enough time for the first location to arrive..

I suggest you to launch the Maps app first, so that there is at least some confirmed location, and then test your app.

Answer from Amit K. Saha on Stack Overflow
🌐
Medium
medium.com › @debuggingisfun › fusedlocationproviderclients-null-location-2e13d6128031
FusedLocationProviderClient’s null location | by Vairavan Srinivasan | Medium
August 21, 2023 - FusedLocationProviderClient supports getCurrentLocation to fetch available current location. However, it is documented to return a null location if unable to fetch it and to make things worse it invokes the success callback with a null location.
🌐
Google
developers.google.com › google play services › fusedlocationproviderclient
FusedLocationProviderClient | Google Play services | Google for Developers
October 31, 2024 - This may return a cached location if a recent enough location fix exists, or may compute a fresh location. If unable to retrieve a current location fix before timing out, null will be returned.
Top answer
1 of 13
73

The fused Location Provider will only maintain background location if at least one client is connected to it. Now just turning on the location service will not guarantee to store the last known location.

Once the first client connects, it will immediately try to get a location. If your activity is the first client to connect and getLastLocation() is invoked right away in onConnected(), that might not be enough time for the first location to arrive..

I suggest you to launch the Maps app first, so that there is at least some confirmed location, and then test your app.

2 of 13
50

As in this post said, The fused Location Provider will only maintain background location if at least one client is connected to it.

But we can skip the process of launching the Google Maps app to get last location by following way.

What we need to do is

  1. We have to request location update from FusedLocationProviderClient
  2. Then we can get the last location from FusedLocationProviderClient, it wouldn't be null.

Request Location

LocationRequest mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(60000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationCallback mLocationCallback = new LocationCallback() {
    @Override
    public void onLocationResult(LocationResult locationResult) {
        if (locationResult == null) {
            return;
        }
        for (Location location : locationResult.getLocations()) {
            if (location != null) {
                //TODO: UI updates.
            }
        }
    }
};
LocationServices.getFusedLocationProviderClient(context).requestLocationUpdates(mLocationRequest, mLocationCallback, null);

Get last location

LocationServices.getFusedLocationProviderClient(context).getLastLocation().addOnSuccessListener(new OnSuccessListener<Location>() {
        @Override
        public void onSuccess(Location location) {
            //TODO: UI updates.
        }
    });

For best result requestLocationUpdates in onStart() of the Activity, and then you can get last location.

🌐
Medium
medium.com › @stevekamau72 › how-to-fix-null-lastlocation-from-fusedlocationproviderclient-6629280a90b4
How to fix null lastLocation from FusedLocationProviderClient | by Steve Kamau | Medium
January 4, 2024 - private fun getDeviceLocation() { val fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(requireContext()) val locationResult = fusedLocationProviderClient.lastLocation locationResult.addOnCompleteListener(requireActivity()) { task -> if (task.isSuccessful) { // i check for the result here, if null it means the location object is null if (task.result == null) { // so we need to find a different way to force this retrieval handleNewLocation() return@addOnCompleteListener } // do what you want with task.result } else { Timber.tag(TAG).d("Current location is null. Using
🌐
Android Developers
developer.android.com › core areas › sensors and location › get the last known location
Get the last known location | Sensors and location | Android Developers
To avoid this situation you can create a new client and request location updates yourself. For more information, see Request location updates. The FusedLocationProviderClient provides several methods to retrieve device location information.
🌐
Stack Overflow
stackoverflow.com › questions › 72078561 › why-does-fusedlocationproviderclient-getcurrentlocation-always-return-a-null-o
android - Why does FusedLocationProviderClient.getCurrentLocation() always return a null object? - Stack Overflow
I am trying to get the location whenever a user clicks a button. I have the code below but the outcome of "location" always is null. I am running this on an emulator in Android Studio and whenever I check out the app info, location services are turned on and location permission is successfully granted.
🌐
Kotlinlang
slack-chats.kotlinlang.org › t › 470120 › hello-everyone-i-am-currently-having-an-issue-with-fusedloca
Hello everyone i am currently having an issue with FusedLoca kotlinlang #android
as per your suggestion I opened the map app and a popup appeared briefly and afterwards showed my current location. When I went back in the app, the "val test" and "val deviceLocation" correctly retrieved the fusedLocation ... requestLocationUpdates and I'd resume the continuation after the first result (Also you should dispose the listener after the first result) ... @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) @SuppressLint("MissingPermission") fun startLocationUpdate() = fusedLocationProviderClient.requestLocationUpdates( locationRequest, locationCallback, Looper.getMainLooper() ) this is what I call every time from a lifecycle aware service binded to the UI
Find elsewhere
🌐
Stack Overflow
stackoverflow.com › questions › 53029418 › fusedlocationprovider-return-null
android - FusedLocationProvider return null - Stack Overflow
and if location null update fused location provider · public void getDeviceLocation() { try { final Task<Location> locationTask = fusedLocationProviderClient.getLastLocation(); locationTask.addOnSuccessListener((Activity) context, new OnSuccessListener<Location>() { @Override public void onSuccess(Location location) { if (location != null) { lastKnownLocation = location; if(map==null){ Toast.makeText(context,"map null",Toast.LENGTH_LONG).show(); return; } map.moveCamera(CameraUpdateFactory.newLatLngZoom( new LatLng(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude()), Constants.
🌐
Stack Overflow
stackoverflow.com › questions › 63223410 › does-fusedlocationproviderclient-need-to-initialize-location-often-null
android - Does FusedLocationProviderClient need to initialize? location often null - Stack Overflow
= p0?.lastLocation if(location != null) { latitude = location.latitude.toString() longitude = location.longitude.toString() } } } ... Save this answer. ... Show activity on this post. The last known location is a cached value that gets wiped from time to time (e.g.
🌐
Stack Overflow
stackoverflow.com › questions › 42209938 › location-is-null-fused-location-provider-android
Location is null Fused location provider android - Stack Overflow
if (isLocationEnabled(getApplicationContext())) { mMenu.getItem(0).setVisible(true); } else { Snackbar.make(mLayout, getString(R.string.loc_not_enable), Snackbar.LENGTH_LONG).show(); } } }); //setup GoogleApiclient buildGoogleApiClient(); public static boolean isLocationEnabled(Context context) { int locationMode = 0; String locationProviders; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){ try { locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE); } catch (SettingNotFoundException e) { e.printStackTrace(); return false; } return locatio
🌐
Medium
droidbyme.medium.com › get-current-location-using-fusedlocationproviderclient-in-android-cb7ebf5ab88e
Get Current location using FusedLocationProviderClient in Android | by Droid By Me | Medium
January 2, 2019 - 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.
🌐
Google
developers.google.com › google play services › fusedlocationproviderapi
FusedLocationProviderApi | Google Play services | Google for Developers
When LocationAvailability.isLo... specified by the active LocationRequests. If the client isn't connected to Google Play services and the request times out, null is returned....
Top answer
1 of 2
14

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:

CopycheckLocationSettings(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)

2 of 2
1

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 :

CopyFusedLocationProviderClient 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 ();
        }
🌐
Stack Overflow
stackoverflow.com › questions › tagged › fusedlocationproviderclient
Newest 'fusedlocationproviderclient' Questions - Stack Overflow
I used FusedLocationProviderClient with JobScheduler to get current location all time and it working well when app in background. But getCurrentLocation() method return Location = null when I tested ...
🌐
Akaver
courses.taltech.akaver.com › 13 - fused location
13 - Fused location | Native Mobile Applications - Courses
March 29, 2026 - -> if (location != null) { locationReceive(location) } else { Log.w(TAG, "Initial location was null") } } } @SuppressLint("MissingPermission") private fun locationReceive(location: Location, updateNotification: Boolean = false) { prevLocation?.apply { distance += location.distanceTo(this) } if (updateNotification) { val notification = buildNotification(this, "Foreground Service", "Distance: $distance") NotificationManagerCompat.from(this).notify(NOTIFICATION_ID, notification) } prevLocation = location } @SuppressLint("MissingPermission") private fun requestLocationUpdates() { if (!permissionsG
Top answer
1 of 2
3

First of all, if you're using the emulator you have to set the position manually doing:

telnet localhost 5554

when connected run the command

geo fix <longitude> <latitude>

as decribed here Using the emulator #geo or here how-to-emulate-gps-location-in-the-android-emulator. I suggest you to do so at soon as the emulator is booting and obviously before you're app start.

Second thing, your FusedLocation isn't implementing LocationListener as it is in the example you have posted. You have to implement that interface and then implement the method onLocationChanged inside your FusedLocation. Anyway, I think that you are trying to load the location as soon as the app is started, right? Well the example you posted doesn't work in this way but it's the user that ask for location through a visible botton. If you want to load the location at the beginning you can modify the example code like this:

the FusedLocationService is your FusedLocation class

import android.app.Activity;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class FusedLocationService implements
        LocationListener,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {

    private static final String TAG = "FusedLocationService";

    private static final long INTERVAL = 1000 * 30;
    private static final long FASTEST_INTERVAL = 1000 * 5;
    private static final long ONE_MIN = 1000 * 60;
    private static final long REFRESH_TIME = ONE_MIN * 5;
    private static final float MINIMUM_ACCURACY = 50.0f;
    Activity locationActivity;
    private LocationRequest locationRequest;
    private GoogleApiClient googleApiClient;
    private Location location;
    private FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;

    FusedLocationReceiver locationReceiver = null;

    public FusedLocationService(Activity locationActivity, FusedLocationReceiver locationReceiver) {
        this.locationReceiver = locationReceiver;
        locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(INTERVAL);
        locationRequest.setFastestInterval(FASTEST_INTERVAL);
        this.locationActivity = locationActivity;

        googleApiClient = new GoogleApiClient.Builder(locationActivity)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();

        if (googleApiClient != null) {
            googleApiClient.connect();
        }
    }

    @Override
    public void onConnected(Bundle connectionHint) {
        Log.i(TAG, "I'm connected now");
        Location currentLocation = fusedLocationProviderApi.getLastLocation(googleApiClient);
        if (currentLocation != null && currentLocation.getTime() > REFRESH_TIME) {
            location = currentLocation;
        } else {
            fusedLocationProviderApi.requestLocationUpdates(googleApiClient, locationRequest, this);
            // Schedule a Thread to unregister location listeners
            Executors.newScheduledThreadPool(1).schedule(new Runnable() {
                @Override
                public void run() {
                    fusedLocationProviderApi.removeLocationUpdates(googleApiClient,
                            FusedLocationService.this);
                }
            }, ONE_MIN, TimeUnit.MILLISECONDS);
        }
    }

    @Override
    public void onLocationChanged(Location location) {
        Log.i(TAG, "Location is changed!");
        //if the existing location is empty or
        //the current location accuracy is greater than existing accuracy
        //then store the current location
        if (null == this.location || location.getAccuracy() < this.location.getAccuracy()) {
            this.location = location;
// let's inform my client class through the receiver
            locationReceiver.onLocationChanged();
            //if the accuracy is not better, remove all location updates for this listener
            if (this.location.getAccuracy() < MINIMUM_ACCURACY) {
                fusedLocationProviderApi.removeLocationUpdates(googleApiClient, this);
            }
        }
    }

    public Location getLocation() {
        return this.location;
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

}

This is the receiver

public abstract class FusedLocationReceiver {
    public abstract void onLocationChanged();
}

and this is the activity

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

import android.app.Activity;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;

public class MainActivity extends Activity {

    private static final String TAG = "MyActivity";
    Button btnFusedLocation;
    TextView tvLocation;
    FusedLocationService fusedLocationService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //show error dialog if GoolglePlayServices not available
        if (!isGooglePlayServicesAvailable()) {
            finish();
        }

        setContentView(R.layout.activity_main);
        tvLocation = (TextView) findViewById(R.id.tvLocation);

        fusedLocationService = new FusedLocationService(this, new FusedLocationReceiver(){

            @Override
            public void onLocationChanged() {
                Log.i(TAG, "I'm the receiver, let's do my job!");
                updateUI();
            }
        });

        btnFusedLocation = (Button) findViewById(R.id.btnGPSShowLocation);
        btnFusedLocation.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                updateUI();
            }
        });
    }

    private void updateUI() {
        Location location = fusedLocationService.getLocation();
        String locationResult = "";
        if (null != location) {
            Log.i(TAG, location.toString());
            double latitude = location.getLatitude();
            double longitude = location.getLongitude();
            float accuracy = location.getAccuracy();
            double elapsedTimeSecs = (double) location.getElapsedRealtimeNanos()
                    / 1000000000.0;
            String provider = location.getProvider();
            double altitude = location.getAltitude();
            locationResult = "Latitude: " + latitude + "\n" +
                    "Longitude: " + longitude + "\n" +
                    "Altitude: " + altitude + "\n" +
                    "Accuracy: " + accuracy + "\n" +
                    "Elapsed Time: " + elapsedTimeSecs + " secs" + "\n" +
                    "Provider: " + provider + "\n";
        } else {
            Log.i(TAG, "Location Not Available!");
            locationResult = "Location Not Available!";
        }
        tvLocation.setText(locationResult);
    }


    private boolean isGooglePlayServicesAvailable() {
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (ConnectionResult.SUCCESS == status) {
            return true;
        } else {
            GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
            return false;
        }
    }
}

Essentially when you instantiate a FusedLocationService you give it an object (the receiver) that will be called by the FusedLocationService when the location is ready. Warning: this will give you the location only once.

2 of 2
2

You please check your location service.

It may be off so turn it on and then test it.

You can also put condition for GPS is enabled or not like:

//exceptions will be thrown if provider is not permitted.
try {
    gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    if(gpsEnabled) {
        // Your Code....
    }
} catch (Exception ex) {
    Log.e("TAG", "GPS Error : " + ex.getLocalizedMessage());
}

Thanks.

🌐
Codepath
guides.codepath.org › android › Retrieving-Location-with-LocationServices-API
Retrieving Location with LocationServices API | Android Development | CodePath Guides
public void getLastLocation() { // Get last known recent location using new Google Play Services SDK (v11+) FusedLocationProviderClient locationClient = getFusedLocationProviderClient(this); locationClient.getLastLocation() .addOnSuccessListener(new OnSuccessListener<Location>() { @Override public void onSuccess(Location location) { // GPS location can be null if GPS is switched off if (location != null) { onLocationChanged(location); } } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Log.d("MapDemoActivity", "Error trying to get last GPS location"); e.printStackTrace(); } }); }