Home » Android » android – Application getting wrong location until open inbuilt Google Map application

android – Application getting wrong location until open inbuilt Google Map application

Posted by: admin May 14, 2020 Leave a comment

Questions:

I have developed one application which is used to find current location of device. I have used Fused Location API to get current location.

I am facing very strange issue, in some of devices i am not getting accurate current location until i open inbuilt Google Map, once i open Google Map and back to my application at that time application return exact location.

Here is my Location Request.

mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT); // 10 meters

Can anyone tell me what is the wrong? Your help is really appreciated.

How to&Answers:

So Waze and we used FusedLocation in past and faced a lot of problems.
The API is broken. There are some devices that not perf it properly. Activity recognition that fused a lot relay not working and recognize staff properly.
We end, to switching back to location manager API.

Here the snippet:

Init location manager and start to request the updates on different thread.
I personally register separate listeners for each provider

if (mLocationManager == null) {
        LOGGER.info("Location track,start called first time. Creating Location Manager");
        mLocationManager = (LocationManager) mContextWeakReference.get()
                .getSystemService(Context.LOCATION_SERVICE);

        mLocationHandlerThread
                = new HandlerThread("LocationThread", Thread.NORM_PRIORITY);
        mLocationHandlerThread.start();
        // Now get the Looper from the HandlerThread
        // NOTE: This call will block until the HandlerThread gets control and initializes its Looper
        Looper looper = mLocationHandlerThread.getLooper();
        Location networkLastKnownLocation = null;
        Location gpsLastKnownLocation = null;
        mGpsLocationListener = new GpsLocationListener();
        mNetworkLocationListener = new NetworkLocationListener();

        // Register the listener with the Location Manager to receive location updates
        if (mLocationManager.getAllProviders().contains(LocationManager.GPS_PROVIDER)) {
            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                    LOCATION_REQUEST_INTERVAL_MILLIS, SMALLEST_DISPLACEMENT_METERS,
                    mGpsLocationListener,
                    looper);

            gpsLastKnownLocation = mLocationManager
                    .getLastKnownLocation(LocationManager.GPS_PROVIDER);
        } else {
            setGpsProviderAvailable(false);
        }
        if (mLocationManager.getAllProviders().contains(LocationManager.NETWORK_PROVIDER)) {
            networkLastKnownLocation = mLocationManager
                    .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
                    LOCATION_REQUEST_INTERVAL_MILLIS, SMALLEST_DISPLACEMENT_METERS,
                    mNetworkLocationListener,
                    looper);
        }

        setLastKnownLocationDifferentProviders(gpsLastKnownLocation,
                networkLastKnownLocation);

    }

And the listeners are:

public class GpsLocationListener implements LocationListener {

    @Override
    public void onLocationChanged(Location location) {
        LOGGER.info("Location track ,onLocationChanged location={}", location);
        switch (location.getProvider()) {
            case LocationManager.GPS_PROVIDER:
                if (mLocationManager != null) {
                    mLocationManager.removeUpdates(mNetworkLocationListener);
                }
                break;
        }
        setLastKnownLocation(location);
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        LOGGER.info("onStatusChanged: {}, status: {}", provider, status);
    }

    @Override
    public void onProviderEnabled(String provider) {
        LOGGER.info("onProviderEnabled: " + provider);
        if (provider.equals(LocationManager.GPS_PROVIDER)) {
            setGpsProviderAvailable(true);
        }
    }

    @Override
    public void onProviderDisabled(String provider) {
        LOGGER.info("onProviderDisabled: " + provider);
        if (provider.equals(LocationManager.GPS_PROVIDER)) {
            setGpsProviderAvailable(false);
        }
    }
}

public class NetworkLocationListener implements LocationListener {

    @Override
    public void onLocationChanged(Location location) {
        LOGGER.info("Location track ,onLocationChanged location={}", location);
        switch (location.getProvider()) {
            case LocationManager.NETWORK_PROVIDER:
                setLastKnownLocation(location);
                break;
        }
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        LOGGER.info("onStatusChanged: {}, status: {}", provider, status);
    }

    @Override
    public void onProviderEnabled(String provider) {
        LOGGER.info("onProviderEnabled: " + provider);
        if (provider.equals(LocationManager.GPS_PROVIDER)) {
            setGpsProviderAvailable(true);
        }
    }

    @Override
    public void onProviderDisabled(String provider) {
        LOGGER.info("onProviderDisabled: " + provider);
        if (provider.equals(LocationManager.GPS_PROVIDER)) {
            setGpsProviderAvailable(false);
        }
    }
}

Don’t forgot to unregister and stop all threads 🙂

Answer:

While creating LocationRequest, You must have setPriority() to PRIORITY_NO_POWER.

PRIORITY_NO_POWER means your app will never get any location unless other app in phone had requested for locations and it received. Read more at LocationRequest.

Answer:

I am not sure about this, but last I had seen anything like this, that phone didn’t not have dedicated GPS. It only had a-GPS.

After toying around for lot of time I realised that this was the reason why I wasn’t getting accurate location. But after opening maps, for some reason location was accurate. Google definitely does lot of other things in maps to fetch accurate location on maps even if the phone doesn’t have dedicated GPS. Just check the devices and their hardware specs.

Answer:

Are you guys testing on Marshmallow or above version device ?
In devices above than Lollipop, You have to request for Location permission at run time. Refer this link http://developer.android.com/training/permissions/requesting.html
So your wouldn’t have location permission,hence it would not return accurate location but when you start your Map app that has already have Gps permission, will update your location in Google play service. So your also start showing correct location because location is ultimately fetched from Google play service.