forked from organicmaps/organicmaps
Merge pull request #5194 from alexzatsepin/add-location-checking-to-onlocationchanged
[android] Added the location fix check to onLocationChanged method
This commit is contained in:
commit
938ee24b0d
12 changed files with 133 additions and 99 deletions
|
@ -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();
|
||||
|
|
|
@ -73,9 +73,4 @@ public class BaseActivityDelegate
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
static boolean onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
return LocationHelper.INSTANCE.onActivityResult(requestCode, resultCode);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<LocationListener> 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<String> filterProviders(LocationManager locationManager)
|
||||
{
|
||||
final List<String> res = locationManager.getProviders(true /* enabledOnly */);
|
||||
Criteria criteria = new Criteria();
|
||||
criteria.setAccuracy(Criteria.ACCURACY_FINE);
|
||||
final List<String> res = locationManager.getProviders(criteria, true /* enabledOnly */);
|
||||
res.remove(LocationManager.PASSIVE_PROVIDER);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<LocationSettingsResult> 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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()
|
||||
|
|
Loading…
Add table
Reference in a new issue