Here is the problem:
LocationMethodsImpl:
=== Cut ===
@Override
public void start() throws RemoteException {
mapLocationManager.startUpdates();
}
@Override
public void stop() throws RemoteException {
mapLocationManager.stopUpdates();
}
=== Cut ===
Here return value from mapLocationManager.startUpdate() is not
checked. I can change that in my own class which will derive from
LocationMethodsImpl (although mapLocationManager is a private field
and there is no getter, however this is doable), but the problem is
further. MapLocationManager.startUpdate() does the following:
MapLocationManager:
=== Cut ===
/** Subscribe for location updates. */
public synchronized boolean startUpdates() {
if (!running) {
running = registerLocationListener();
if (DEBUG) { Log.d(LOGTAG, "Starting updates, running = " +
running); }
} else {
if (DEBUG) { Log.d(LOGTAG, "Updates already running"); }
}
return running;
}
=== Cut ===
so if registerLocationListener() returns false then
MapLocationManager.startUpdate() should return false which seems very
correct by the intention. However LocationManager.isProviderEnabled()
is never checked in MapLocationManager.registerLocationListener() and
the following code:
MapLocationManager.registerLocationListener():
=== Cut ===
coarseProvider = locman.getBestProvider(c, false);
if (providers.contains(LocationManager.GPS_PROVIDER)) {
fineProvider = LocationManager.GPS_PROVIDER;
=== Cut ===
just gets executed normally. So even if user disabled locations in
Android preferences MapLocationmanager.registerLocationListener() will
return true and behave as if everything is normal. What will happen is
that MapLocationManager.updateLocation() will never be called.
So in order to implement the dialog "You've disabled geo-location
support, blah-blah" and buttons (Settings/Cancel) we need to check
LocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) and
probably some other code to check whether WiFi and GSM location
updates are enabled to show this kind of dialog.
This is a problem since LocationMethodsImpl hides implementation
details about location and to make a dialog we will need to make
assumptions that LocationMethodsImpl uses LocationManager.
Here's what can be done:
- LocationManager should be available via some getter in
LocationMethodsImpl. This is probably the worst solution since it will
reveal implementation details of LocationMethodsImpls
- There should be a method in LocationMethodsImpl which will allow to
check whether user has disabled updates in Android settings. This
would be the best option.
- LocationManagerImpl should have a getter for MapLocationManager and
MapLocationManager.startIUpdates() should return false in case user
has disabled location updates in her Android
I will currently do the following for my project:
=== Cut ===
So in order to implement the dialog "You've disabled geo-location
support, blah-blah" and buttons (Settings/Cancel) we need to check
LocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) and
probably some other code to check whether WiFi and GSM location
updates are enabled to show this kind of dialog.
=== Cut ===
but this is not nice. So if you have some other hints on how to do it
better or can change the library quick enough - it would be great!
PS Here's what happens in Kinopoisk application (the same issue):
http://my.jetscreenshot.com/11094/20120215-1q5t-25kb
This will be hanging like that to infinity if user has disabled
location update in Android preferences. No dialog about that will be
shown, everything will seem to work well from the code, but the update
location callback will never be called.