Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) always returns NULL on Galaxy S7 (ONLY)

Just received a Galaxy S7 (Edge) running Marshmallow (6.0.1) and find that it has an issue with my app that uses android.permission.ACCESS_COARSE_LOCATION and targets Sdk Version 22 (Lollipop). When I call locationManager.getLastKnownLocation() it always returns NULL. Here's what I'm running:

public Location getLastKnownLocationObject(Context context) {

    LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

    try {
        if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
            Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            // Location is always null on S7 (only)
            Log.i(TAG, ">>> getLastKnownLocationObject() getLastKnownLocation: " + location);
            return location;
        }

    } catch (Exception e) {
        Log.e(TAG, ">>> getLastKnownLocationObject() exception", e);
    }
    return null;

}

This same code works fine on every other device I've tried: Galaxy S5 (5.0.1), Nexus 7 (5.0.1), Nexus 9 (6.0.1), and Samsung Tab3 (4.4.2)

Note that if I change the manifest to use ACCESS_FINE_LOCATION, the above code works fine on every device. Unfortunately, management won't allow me to change permissions at this time.

In a few answers I've seen here on SO, it's suggested to call the following prior to doing the getLastKnownLocation(), but that didn't have any effect.

locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER, 0, 0, new LocationListener() {
                            @Override
                            public void onStatusChanged(String provider, int status, Bundle extras) {
                            }

                            @Override
                            public void onProviderEnabled(String provider) {
                            }

                            @Override
                            public void onProviderDisabled(String provider) {
                            }

                            @Override
                            public void onLocationChanged(final Location location) {
                                // NEVER CALLED on Samsung S7 for LocationManager.NETWORK_PROVIDER
                            }
                        });

So at the moment, I feel this is an issue exclusive to the new Samsung Galaxy S7.

like image 333
GaryAmundson Avatar asked Mar 15 '16 17:03

GaryAmundson


2 Answers

From my experience with Samsung devices. If you reboot the phone and you DON'T enable GPS you will not get a location. If you enable GPS as some point - maybe by running Google Maps, then you will get a location. Samsung does not return a location for GPS, Network or Passive providers unless it has gotten a location during the devices power on cycle.

None of the calls I have made in code ever get it to kick in and activate and get a location. They work fine on other devices. Samsung does not seem to cache this information for very long either.

like image 179
Kevin Avatar answered Sep 23 '22 07:09

Kevin


Well, you are calling isProviderEnabled() so at least that is covered and using the network location should be enabled. However the exact wording of the documentation is:

"If the user has enabled this provider in the Settings menu, true is returned otherwise false is returned"

So it's just about the provider being "enabled" as in not being turned off by the user.

Does the problematic phone (the S7) have a SIM card inside? It's possible that on that specific device the network based positioning requires a SIM card or internet connection.

Referring to the the documentation you could check what these return:

locationManager.getProvider(LocationManager.NETWORK_PROVIDER).requiresCell();
locationManager.getProvider(LocationManager.NETWORK_PROVIDER).requiresNetwork();

And of course just calling getLastKnownLocation() will return null if the location is unknown. And it's unknown if no application (yours or some other) has specifically requested the device to determine its location. So the suggestion to call requestLocationUpdates() is the correct advice. But it may take a while to determine the location so calling getLastKnownLocation() right after probably still returns null.

And even if it returns something, it might be very old data that's not even valid anymore. So why not just subscribe to receive location updates? That's the way it's intended. You are using network based positioning so it won't (at all/significantly) affect power consumption and the updates won't come too often if you specify time interval and distance limits that suit your needs.

like image 34
Markus Kauppinen Avatar answered Sep 26 '22 07:09

Markus Kauppinen