From 1e832a6720aeddbfeec4442efaf02267bf8e1ca7 Mon Sep 17 00:00:00 2001 From: Gary Mathews Date: Wed, 15 Jan 2020 10:11:05 -0800 Subject: [PATCH] fix(android)(8_3_X): getCurrentPosition() compatibility with some Samsung devices (#11426) * fix(android): getCurrentPosition() compatibility with Samsung devices * fix(android): only register location provider when necessary * fix(android): return error when provider is unavailable * fix(android): clone callback array Co-authored-by: Christopher Williams --- .../geolocation/GeolocationModule.java | 69 ++++++++++++------- 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/android/modules/geolocation/src/java/ti/modules/titanium/geolocation/GeolocationModule.java b/android/modules/geolocation/src/java/ti/modules/titanium/geolocation/GeolocationModule.java index d007c8c9d30..4790f173390 100644 --- a/android/modules/geolocation/src/java/ti/modules/titanium/geolocation/GeolocationModule.java +++ b/android/modules/geolocation/src/java/ti/modules/titanium/geolocation/GeolocationModule.java @@ -119,7 +119,7 @@ public class GeolocationModule extends KrollModule implements Handler.Callback, private static final double SIMPLE_LOCATION_PASSIVE_DISTANCE = 0.0; private static final double SIMPLE_LOCATION_PASSIVE_TIME = 0; private static final double SIMPLE_LOCATION_NETWORK_DISTANCE = 10.0; - private static final double SIMPLE_LOCATION_NETWORK_TIME = 10000; + private static final double SIMPLE_LOCATION_NETWORK_TIME = 3000; private static final double SIMPLE_LOCATION_GPS_DISTANCE = 3.0; private static final double SIMPLE_LOCATION_GPS_TIME = 3000; private static final double SIMPLE_LOCATION_NETWORK_DISTANCE_RULE = 200; @@ -136,6 +136,7 @@ public class GeolocationModule extends KrollModule implements Handler.Callback, //currentLocation is conditionally updated. lastLocation is unconditionally updated //since currentLocation determines when to send out updates, and lastLocation is passive private Location lastLocation; + private ArrayList currentPositionCallback = new ArrayList<>(); private FusedLocationProvider fusedLocationProvider; @@ -200,6 +201,20 @@ public boolean handleMessage(Message message) public void onLocationChanged(Location location) { lastLocation = location; + + // Execute current position callbacks. + if (currentPositionCallback.size() > 0) { + ArrayList currentPositionCallbackClone = + (ArrayList) currentPositionCallback.clone(); + currentPositionCallback.clear(); + for (KrollFunction callback : currentPositionCallbackClone) { + callback.call(this.getKrollObject(), + new Object[] { buildLocationEvent( + lastLocation, tiLocation.locationManager.getProvider(lastLocation.getProvider())) }); + } + } + + // Fire 'location' event listeners. if (shouldUseUpdate(location)) { fireEvent(TiC.EVENT_LOCATION, buildLocationEvent(location, tiLocation.locationManager.getProvider(location.getProvider()))); @@ -225,50 +240,42 @@ public void onProviderStateChanged(String providerName, int state) switch (state) { case LocationProviderProxy.STATE_DISABLED: message += " is disabled"; - Log.i(TAG, message, Log.DEBUG_MODE); - fireEvent(TiC.EVENT_LOCATION, buildLocationErrorEvent(state, message)); - break; case LocationProviderProxy.STATE_ENABLED: message += " is enabled"; - Log.d(TAG, message, Log.DEBUG_MODE); - break; case LocationProviderProxy.STATE_OUT_OF_SERVICE: message += " is out of service"; - Log.d(TAG, message, Log.DEBUG_MODE); - fireEvent(TiC.EVENT_LOCATION, buildLocationErrorEvent(state, message)); - break; case LocationProviderProxy.STATE_UNAVAILABLE: message += " is unavailable"; - Log.d(TAG, message, Log.DEBUG_MODE); - fireEvent(TiC.EVENT_LOCATION, buildLocationErrorEvent(state, message)); - break; case LocationProviderProxy.STATE_AVAILABLE: message += " is available"; - Log.d(TAG, message, Log.DEBUG_MODE); - break; case LocationProviderProxy.STATE_UNKNOWN: - message += " is in a unknown state [" + state + "]"; - Log.d(TAG, message, Log.DEBUG_MODE); - fireEvent(TiC.EVENT_LOCATION, buildLocationErrorEvent(state, message)); - - break; - default: message += " is in a unknown state [" + state + "]"; - Log.d(TAG, message, Log.DEBUG_MODE); - fireEvent(TiC.EVENT_LOCATION, buildLocationErrorEvent(state, message)); - - break; + } + Log.d(TAG, message, Log.DEBUG_MODE); + + if (state != LocationProviderProxy.STATE_ENABLED && state != LocationProviderProxy.STATE_AVAILABLE) { + fireEvent(TiC.EVENT_LOCATION, buildLocationErrorEvent(state, message)); + + // Execute current position callbacks. + if (currentPositionCallback.size() > 0) { + ArrayList currentPositionCallbackClone = + (ArrayList) currentPositionCallback.clone(); + currentPositionCallback.clear(); + for (KrollFunction callback : currentPositionCallbackClone) { + callback.call(this.getKrollObject(), new Object[] { buildLocationErrorEvent(state, message) }); + } + } } } @@ -670,6 +677,20 @@ public void getCurrentPosition(KrollFunction callback) } if (callback != null) { Location latestKnownLocation = tiLocation.getLastKnownLocation(); + if (latestKnownLocation == null) { + latestKnownLocation = lastLocation; + } + + // TIMOB-27572: Samsung devices require a location provider to be registered + // in order to obtain last known location. + if (latestKnownLocation == null) { + if (numLocationListeners == 0) { + numLocationListeners++; + enableLocationProviders(simpleLocationProviders); + } + currentPositionCallback.add(callback); + return; + } if (latestKnownLocation != null) { callback.call(