Search code examples
androidandroid-studiolocationmanager

How to force a location update on Android


Is there an alternative to this call that will force the acquisition of new coordinates from the hardware?

locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

The specific problem I'm having is they are using Fake GPS to mock a location. They turn it off before launching my app, but when my app launches and makes the above call it's still getting the last-given mock location.

Note: We've removed it from the Developer Options as the mock gps provider and done a force quit on it. We even uninstalled it. So I'm certain that Android itself is still caching the prior mock value and just feeding that to my app because the phone hasn't moved.

In addition, because there's no mock provider in Developer Options, Android LocationManager is reporting the cached fake location as NOT mocked. Clearly a huge bug.

What I'd like to do is make a call that FORCES the phone to turn on GPS and acquire new coordinates. Unfortunately I don't see any way to do this...


Solution

  • Short answer is you have to make location request for the said provider. Provider needs a fresh location.

    Long asnwer is;

    The specific problem I'm having is they are using Fake GPS to mock a location. They turn it off before launching my app, but when my app launches and makes the above call it's still getting the last-given mock location.

    Under normal circumstances getLastKnownLocation method returns the cached location for given provider. So getting the mock location is expected in your case, because your device did not receive fresh location yet

    Note: We've removed it from the Developer Options as the mock gps provider and done a force quit on it. We even uninstalled it. So I'm certain that Android itself is still caching the prior mock value and just feeding that to my app because the phone hasn't moved.

    That's right, because the mocker app's previously set location is cached for given provider. It affects the whole system. This is why it's not cleared after uninstalling the mocker app. You have to make location request for the provider or restart your device.

    In addition, because there's no mock provider in Developer Options, Android LocationManager is reporting the cached fake location as NOT mocked. Clearly a huge bug.

    How did you test it ? All devices behave like this when you test ? Maybe the mocker app is installed as system app, so it reports location to LocationManager and dissimulates you ?


    To force GPS to get location you can easily use below code. onLocationChanged method will be triggered by GPS hardware.

    But be sure that a mock location app is not working at this time. Otherwise, onLocationChanged method will be triggered by mocker app !

    private void requestLocation(){
        locationManager.requestLocationUpdates(
        LocationManager.GPS_PROVIDER, 0, 0, mListener);
    }
    
    private LocationListener mListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            // Previously mock location is cleared.
            // getLastKnownLocation(LocationManager.GPS_PROVIDER); will not return mock location. 
        }
    
        ...
    };