Application getting wrong location until open inbuilt Google Map application
Asked Answered
C

4

12

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.

Celerity answered 17/2, 2016 at 12:5 Comment(4)
What's your LocationRequest?Bagasse
C'mon you've got 33k points. Should I guess the concrete values? Please put it in the question not in the comments. Was High accuracy enabled in the phone settings? How many location updates have you received? What devices have you tested on? Whats the version of GMS library used? Anything you can think of helps.Bagasse
Been a member for 5 years, still postinng code in the comments. Oh boy ...Krein
Which devices did you use?Darya
T
4

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 :)

Thunderhead answered 7/4, 2016 at 15:59 Comment(3)
Do I always need a separate thread for this listener? My user walks relatively slowly, and I don't need high frequency updates; Also, the location is simply pushed for further processing: nothing will get stuck on the UI thread.Outfox
Another question: there is this whole wisdom of how to filter out "wrong" location updates.Outfox
1. No. You don't need separate thread for this. You can use same UI thread to get onLocationChange 2. It's the whole different story :) Need to write book how to filter out bad locationsThunderhead
C
0

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.

Chart answered 17/2, 2016 at 12:36 Comment(0)
A
0

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.

Ahn answered 17/2, 2016 at 12:40 Comment(1)
You show how the issue can be reliably reproduced, not how it can be fixed.Outfox
F
-1

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.

Fitts answered 6/4, 2016 at 17:27 Comment(1)
That's not correct. The app is marked as targeting Lollipop, and therefore even on Marshmallow the permissions work the old way. Also, location updates do arrive, only less accurate than with Maps. Also, if I switch to GPS location provider from fused, the updates work just fine.Outfox

© 2022 - 2024 — McMap. All rights reserved.