diff --git a/android/src/com/mapswithme/maps/MwmActivity.java b/android/src/com/mapswithme/maps/MwmActivity.java index 329a401fad..4b570541b5 100644 --- a/android/src/com/mapswithme/maps/MwmActivity.java +++ b/android/src/com/mapswithme/maps/MwmActivity.java @@ -1787,7 +1787,6 @@ public class MwmActivity extends BaseMwmFragmentActivity @Override public void onClick(DialogInterface dialog, int which) { - //TODO: try to use startActivityForResult to handle settings result back startActivity(intent); } }).show(); diff --git a/android/src/com/mapswithme/maps/base/BaseActivityDelegate.java b/android/src/com/mapswithme/maps/base/BaseActivityDelegate.java index c3e89e1e67..fa821b27c3 100644 --- a/android/src/com/mapswithme/maps/base/BaseActivityDelegate.java +++ b/android/src/com/mapswithme/maps/base/BaseActivityDelegate.java @@ -73,9 +73,4 @@ public class BaseActivityDelegate } }); } - - static boolean onActivityResult(int requestCode, int resultCode, Intent data) - { - return LocationHelper.INSTANCE.onActivityResult(requestCode, resultCode); - } } diff --git a/android/src/com/mapswithme/maps/base/BaseMwmFragmentActivity.java b/android/src/com/mapswithme/maps/base/BaseMwmFragmentActivity.java index 34087dd9ac..5fb29c0232 100644 --- a/android/src/com/mapswithme/maps/base/BaseMwmFragmentActivity.java +++ b/android/src/com/mapswithme/maps/base/BaseMwmFragmentActivity.java @@ -172,13 +172,6 @@ public class BaseMwmFragmentActivity extends AppCompatActivity mBaseDelegate.onPause(); } - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) - { - if (!BaseActivityDelegate.onActivityResult(requestCode, resultCode, data)) - super.onActivityResult(requestCode, resultCode, data); - } - protected Toolbar getToolbar() { return (Toolbar) findViewById(R.id.toolbar); diff --git a/android/src/com/mapswithme/maps/location/AndroidNativeProvider.java b/android/src/com/mapswithme/maps/location/AndroidNativeProvider.java index 2fc99c1366..5780128380 100644 --- a/android/src/com/mapswithme/maps/location/AndroidNativeProvider.java +++ b/android/src/com/mapswithme/maps/location/AndroidNativeProvider.java @@ -1,6 +1,7 @@ package com.mapswithme.maps.location; import android.content.Context; +import android.location.Criteria; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; @@ -20,8 +21,9 @@ class AndroidNativeProvider extends BaseLocationProvider @NonNull private final List mListeners = new ArrayList<>(); - AndroidNativeProvider() + AndroidNativeProvider(@NonNull LocationFixChecker locationFixChecker) { + super(locationFixChecker); mLocationManager = (LocationManager) MwmApplication.get().getSystemService(Context.LOCATION_SERVICE); } @@ -38,7 +40,8 @@ class AndroidNativeProvider extends BaseLocationProvider mIsActive = true; for (String provider : providers) { - LocationListener listener = new BaseLocationListener(); + sLogger.d("Request location updates from the provider: " + provider); + LocationListener listener = new BaseLocationListener(getLocationFixChecker()); mLocationManager.requestLocationUpdates(provider, LocationHelper.INSTANCE.getInterval(), 0, listener); mListeners.add(listener); } @@ -47,7 +50,7 @@ class AndroidNativeProvider extends BaseLocationProvider Location location = findBestNotExpiredLocation(mLocationManager, providers, LocationUtils.LOCATION_EXPIRATION_TIME_MILLIS_SHORT); - if (!isLocationBetterThanLast(location)) + if (!getLocationFixChecker().isLocationBetterThanLast(location)) { location = LocationHelper.INSTANCE.getSavedLocation(); if (location == null || LocationUtils.isExpired(location, LocationHelper.INSTANCE.getSavedLocationTime(), @@ -106,7 +109,9 @@ class AndroidNativeProvider extends BaseLocationProvider @NonNull private static List filterProviders(LocationManager locationManager) { - final List res = locationManager.getProviders(true /* enabledOnly */); + Criteria criteria = new Criteria(); + criteria.setAccuracy(Criteria.ACCURACY_FINE); + final List res = locationManager.getProviders(criteria, true /* enabledOnly */); res.remove(LocationManager.PASSIVE_PROVIDER); return res; } diff --git a/android/src/com/mapswithme/maps/location/BaseLocationListener.java b/android/src/com/mapswithme/maps/location/BaseLocationListener.java index 20d06e5ba2..213d486872 100644 --- a/android/src/com/mapswithme/maps/location/BaseLocationListener.java +++ b/android/src/com/mapswithme/maps/location/BaseLocationListener.java @@ -3,6 +3,7 @@ package com.mapswithme.maps.location; import android.location.Location; import android.location.LocationListener; import android.os.Bundle; +import android.support.annotation.NonNull; import com.mapswithme.util.log.DebugLogger; import com.mapswithme.util.log.Logger; @@ -10,6 +11,13 @@ import com.mapswithme.util.log.Logger; class BaseLocationListener implements LocationListener, com.google.android.gms.location.LocationListener { private static final Logger LOGGER = new DebugLogger(BaseLocationListener.class.getSimpleName()); + @NonNull + private final LocationFixChecker mLocationFixChecker; + + BaseLocationListener(@NonNull LocationFixChecker locationFixChecker) + { + mLocationFixChecker = locationFixChecker; + } @Override public void onLocationChanged(Location location) @@ -18,9 +26,21 @@ class BaseLocationListener implements LocationListener, com.google.android.gms.l if (location.getAccuracy() <= 0.0) return; - LocationHelper.INSTANCE.resetMagneticField(location); - LocationHelper.INSTANCE.onLocationUpdated(location); - LocationHelper.INSTANCE.notifyLocationUpdated(); + if (mLocationFixChecker.isLocationBetterThanLast(location)) + { + LocationHelper.INSTANCE.resetMagneticField(location); + LocationHelper.INSTANCE.onLocationUpdated(location); + LocationHelper.INSTANCE.notifyLocationUpdated(); + } + else + { + Location last = LocationHelper.INSTANCE.getSavedLocation(); + if (last != null) + { + LOGGER.d("The new location from '" + location.getProvider() + + "' is worse than the last one from '" + last.getProvider() + "'"); + } + } } @Override diff --git a/android/src/com/mapswithme/maps/location/BaseLocationProvider.java b/android/src/com/mapswithme/maps/location/BaseLocationProvider.java index eca89437db..d25fbb074b 100644 --- a/android/src/com/mapswithme/maps/location/BaseLocationProvider.java +++ b/android/src/com/mapswithme/maps/location/BaseLocationProvider.java @@ -1,31 +1,25 @@ package com.mapswithme.maps.location; -import android.location.Location; -import android.support.annotation.Nullable; +import android.support.annotation.NonNull; -import com.mapswithme.util.LocationUtils; import com.mapswithme.util.log.Logger; import com.mapswithme.util.log.SimpleLogger; abstract class BaseLocationProvider { static final Logger sLogger = SimpleLogger.get(BaseLocationProvider.class.getName()); - private static final double DEFAULT_SPEED_MPS = 5; + @NonNull + private final LocationFixChecker mLocationFixChecker; - boolean isLocationBetterThanLast(@Nullable Location newLocation) + @NonNull + LocationFixChecker getLocationFixChecker() { - if (newLocation == null) - return false; - - final Location lastLocation = LocationHelper.INSTANCE.getSavedLocation(); - return (lastLocation == null || isLocationBetterThanLast(newLocation, lastLocation)); + return mLocationFixChecker; } - boolean isLocationBetterThanLast(Location newLocation, Location lastLocation) + BaseLocationProvider(@NonNull LocationFixChecker locationFixChecker) { - double speed = Math.max(DEFAULT_SPEED_MPS, (newLocation.getSpeed() + lastLocation.getSpeed()) / 2.0); - double lastAccuracy = (lastLocation.getAccuracy() + speed * LocationUtils.getDiff(lastLocation, newLocation)); - return (newLocation.getAccuracy() < lastAccuracy); + mLocationFixChecker = locationFixChecker; } /** diff --git a/android/src/com/mapswithme/maps/location/DefaultLocationFixChecker.java b/android/src/com/mapswithme/maps/location/DefaultLocationFixChecker.java new file mode 100644 index 0000000000..d40ed7632c --- /dev/null +++ b/android/src/com/mapswithme/maps/location/DefaultLocationFixChecker.java @@ -0,0 +1,29 @@ +package com.mapswithme.maps.location; + +import android.location.Location; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.mapswithme.util.LocationUtils; + +class DefaultLocationFixChecker implements LocationFixChecker +{ + private static final double DEFAULT_SPEED_MPS = 5; + + @Override + public boolean isLocationBetterThanLast(@Nullable Location newLocation) + { + if (newLocation == null) + return false; + + final Location lastLocation = LocationHelper.INSTANCE.getSavedLocation(); + return lastLocation == null || isLocationBetterThanLast(newLocation, lastLocation); + } + + boolean isLocationBetterThanLast(@NonNull Location newLocation, @NonNull Location lastLocation) + { + double speed = Math.max(DEFAULT_SPEED_MPS, (newLocation.getSpeed() + lastLocation.getSpeed()) / 2.0); + double lastAccuracy = lastLocation.getAccuracy() + speed * LocationUtils.getDiff(lastLocation, newLocation); + return newLocation.getAccuracy() < lastAccuracy; + } +} diff --git a/android/src/com/mapswithme/maps/location/FusedLocationFixChecker.java b/android/src/com/mapswithme/maps/location/FusedLocationFixChecker.java new file mode 100644 index 0000000000..fe4ba5cf7e --- /dev/null +++ b/android/src/com/mapswithme/maps/location/FusedLocationFixChecker.java @@ -0,0 +1,22 @@ +package com.mapswithme.maps.location; + +import android.location.Location; +import android.support.annotation.NonNull; + +class FusedLocationFixChecker extends DefaultLocationFixChecker +{ + private static final String GMS_LOCATION_PROVIDER = "fused"; + + @Override + boolean isLocationBetterThanLast(@NonNull Location newLocation, @NonNull Location lastLocation) + { + // We believe that google services always return good locations. + return isFromFusedProvider(newLocation) || + (!isFromFusedProvider(lastLocation) && super.isLocationBetterThanLast(newLocation, lastLocation)); + } + + private static boolean isFromFusedProvider(Location location) + { + return GMS_LOCATION_PROVIDER.equalsIgnoreCase(location.getProvider()); + } +} diff --git a/android/src/com/mapswithme/maps/location/GPSCheck.java b/android/src/com/mapswithme/maps/location/GPSCheck.java index 2121949be5..f183b2e3ec 100644 --- a/android/src/com/mapswithme/maps/location/GPSCheck.java +++ b/android/src/com/mapswithme/maps/location/GPSCheck.java @@ -3,8 +3,6 @@ package com.mapswithme.maps.location; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.location.LocationManager; -import android.util.Log; import com.mapswithme.maps.MwmApplication; @@ -12,15 +10,7 @@ public class GPSCheck extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - - LocationManager locationManager = (LocationManager) context.getSystemService(context.LOCATION_SERVICE); - - if ((locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) - || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) - && MwmApplication.get().isFrameworkInitialized() && MwmApplication.backgroundTracker().isForeground()) - { - LocationHelper.INSTANCE.addLocationListener(); - LocationHelper.INSTANCE.forceRestart(); - } + if (MwmApplication.get().isFrameworkInitialized() && MwmApplication.backgroundTracker().isForeground()) + LocationHelper.INSTANCE.checkProvidersAndStartIfNeeded(); } -} \ No newline at end of file +} diff --git a/android/src/com/mapswithme/maps/location/GoogleFusedLocationProvider.java b/android/src/com/mapswithme/maps/location/GoogleFusedLocationProvider.java index b15c39d189..4870f3cfe1 100644 --- a/android/src/com/mapswithme/maps/location/GoogleFusedLocationProvider.java +++ b/android/src/com/mapswithme/maps/location/GoogleFusedLocationProvider.java @@ -20,33 +20,21 @@ class GoogleFusedLocationProvider extends BaseLocationProvider implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { - private static final String GMS_LOCATION_PROVIDER = "fused"; private final GoogleApiClient mGoogleApiClient; private LocationRequest mLocationRequest; private PendingResult mLocationSettingsResult; @NonNull - private final BaseLocationListener mListener = new BaseLocationListener(); + private final BaseLocationListener mListener; - GoogleFusedLocationProvider() + GoogleFusedLocationProvider(@NonNull LocationFixChecker locationFixChecker) { + super(locationFixChecker); mGoogleApiClient = new GoogleApiClient.Builder(MwmApplication.get()) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); - } - - @Override - boolean isLocationBetterThanLast(Location newLocation, Location lastLocation) - { - // We believe that google services always return good locations. - return (isFromFusedProvider(newLocation) || - (!isFromFusedProvider(lastLocation) && super.isLocationBetterThanLast(newLocation, lastLocation))); - } - - private static boolean isFromFusedProvider(Location location) - { - return GMS_LOCATION_PROVIDER.equalsIgnoreCase(location.getProvider()); + mListener = new BaseLocationListener(locationFixChecker); } @Override @@ -141,7 +129,7 @@ class GoogleFusedLocationProvider extends BaseLocationProvider LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mListener); LocationHelper.INSTANCE.startSensors(); Location last = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); - if (last != null && isLocationBetterThanLast(last)) + if (last != null) mListener.onLocationChanged(last); } diff --git a/android/src/com/mapswithme/maps/location/LocationFixChecker.java b/android/src/com/mapswithme/maps/location/LocationFixChecker.java new file mode 100644 index 0000000000..5fc3dd4903 --- /dev/null +++ b/android/src/com/mapswithme/maps/location/LocationFixChecker.java @@ -0,0 +1,9 @@ +package com.mapswithme.maps.location; + +import android.location.Location; +import android.support.annotation.Nullable; + +interface LocationFixChecker +{ + boolean isLocationBetterThanLast(@Nullable Location newLocation); +} diff --git a/android/src/com/mapswithme/maps/location/LocationHelper.java b/android/src/com/mapswithme/maps/location/LocationHelper.java index 3e813d3072..e809174d30 100644 --- a/android/src/com/mapswithme/maps/location/LocationHelper.java +++ b/android/src/com/mapswithme/maps/location/LocationHelper.java @@ -1,6 +1,7 @@ package com.mapswithme.maps.location; import android.app.Activity; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; @@ -10,8 +11,6 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.app.AlertDialog; -import java.lang.ref.WeakReference; - import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GoogleApiAvailability; import com.mapswithme.maps.Framework; @@ -29,6 +28,7 @@ import com.mapswithme.util.log.DebugLogger; import com.mapswithme.util.log.Logger; import static com.mapswithme.maps.background.AppBackgroundTracker.*; +import java.lang.ref.WeakReference; public enum LocationHelper { @@ -51,7 +51,6 @@ public enum LocationHelper private static final long INTERVAL_NAVIGATION_PEDESTRIAN_MS = 1000; private static final long STOP_DELAY_MS = 5000; - static final int REQUEST_RESOLVE_ERROR = 101; private boolean mErrorOccurred; @@ -132,13 +131,11 @@ public enum LocationHelper { mErrorOccurred = true; mLogger.d("onLocationError errorCode = " + errorCode); - if (mLocationStopped) - return; nativeOnLocationError(errorCode); - mLogger.d("nativeOnLocationError errorCode = " + errorCode +", " + - "state machine should stop pending, current state = " - + LocationState.nameOf(LocationState.getMode())); + mLogger.d("nativeOnLocationError errorCode = " + errorCode + + ", current state = " + LocationState.nameOf(LocationState.getMode())); + stop(); if (mUiCallback == null) return; @@ -269,12 +266,12 @@ public enum LocationHelper googleServicesTurnedInSettings) { mLogger.d("Use fused provider."); - mLocationProvider = new GoogleFusedLocationProvider(); + mLocationProvider = new GoogleFusedLocationProvider(new FusedLocationFixChecker()); } else { mLogger.d("Use native provider."); - mLocationProvider = new AndroidNativeProvider(); + mLocationProvider = new AndroidNativeProvider(new DefaultLocationFixChecker()); } mActive = !mListeners.isEmpty(); @@ -455,18 +452,25 @@ public enum LocationHelper removeListener(mLocationListener, false); } - public boolean onActivityResult(int requestCode, int resultCode) + void checkProvidersAndStartIfNeeded() { - if (requestCode != REQUEST_RESOLVE_ERROR) - return false; + Context context = MwmApplication.get(); + LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + boolean networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); + boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); + mLocationStopped = !networkEnabled && !gpsEnabled; + mLogger.d("Providers availability: " + !mLocationStopped + + "; network provider = " + networkEnabled + ", gps provider = " + gpsEnabled); - mLocationStopped = (resultCode != Activity.RESULT_OK); - mLogger.d("onActivityResult(): success: " + !mLocationStopped); + if (mLocationStopped) + { + if (LocationState.getMode() == LocationState.PENDING_POSITION) + notifyLocationError(ERROR_DENIED); + return; + } - if (!mLocationStopped) - LocationState.nativeSwitchToNextMode(); - - return true; + initProvider(false); + LocationState.nativeSwitchToNextMode(); } /** @@ -635,17 +639,6 @@ public enum LocationHelper } } - public void forceRestart() - { - mActive = !mListeners.isEmpty(); - if (mActive) - { - calcParams(); - stopInternal(); - startInternal(); - } - } - /** * Actually starts location polling. */ @@ -715,11 +708,8 @@ public enum LocationHelper if (!mLocationStopped) addListener(mLocationListener, true); - } - - public void addLocationListener() - { - addListener(mLocationListener, true); + else + checkProvidersAndStartIfNeeded(); } private void compareWithPreviousCallback()