forked from organicmaps/organicmaps
[android] Refactored geolocation a bit.
This commit is contained in:
parent
69ddc9ea2f
commit
9f0bade6e8
6 changed files with 74 additions and 90 deletions
|
@ -1345,7 +1345,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onLocationUpdated(Location location)
|
||||
public void onLocationUpdated(@NonNull Location location)
|
||||
{
|
||||
if (!mPlacePage.isHidden())
|
||||
mPlacePage.refreshLocation(location);
|
||||
|
@ -1360,7 +1360,7 @@ public class MwmActivity extends BaseMwmFragmentActivity
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onCompassUpdated(CompassData compass)
|
||||
public void onCompassUpdated(@NonNull CompassData compass)
|
||||
{
|
||||
MapFragment.nativeCompassUpdated(compass.getMagneticNorth(), compass.getTrueNorth(), false);
|
||||
mPlacePage.refreshAzimuth(compass.getNorth());
|
||||
|
|
|
@ -3,9 +3,9 @@ package com.mapswithme.maps.location;
|
|||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
import android.location.LocationManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
|
@ -27,7 +27,7 @@ class AndroidNativeProvider extends BaseLocationProvider
|
|||
if (mIsActive)
|
||||
return true;
|
||||
|
||||
List<String> providers = filterProviders();
|
||||
List<String> providers = filterProviders(mLocationManager);
|
||||
if (providers.isEmpty())
|
||||
return false;
|
||||
|
||||
|
@ -37,13 +37,16 @@ class AndroidNativeProvider extends BaseLocationProvider
|
|||
|
||||
LocationHelper.INSTANCE.startSensors();
|
||||
|
||||
Location location = findBestNotExpiredLocation(providers, LocationUtils.LOCATION_EXPIRATION_TIME_MILLIS_SHORT);
|
||||
Location location = findBestNotExpiredLocation(mLocationManager, providers,
|
||||
LocationUtils.LOCATION_EXPIRATION_TIME_MILLIS_SHORT);
|
||||
if (!isLocationBetterThanLast(location))
|
||||
{
|
||||
location = LocationHelper.INSTANCE.getSavedLocation();
|
||||
if (location == null || LocationUtils.isExpired(location, LocationHelper.INSTANCE.getSavedLocationTime(),
|
||||
LocationUtils.LOCATION_EXPIRATION_TIME_MILLIS_SHORT))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
onLocationChanged(location);
|
||||
|
@ -58,35 +61,35 @@ class AndroidNativeProvider extends BaseLocationProvider
|
|||
}
|
||||
|
||||
@Nullable
|
||||
Location findBestNotExpiredLocation(List<String> providers, long expirationMs)
|
||||
public static Location findBestNotExpiredLocation(long expirationMillis)
|
||||
{
|
||||
final LocationManager manager = (LocationManager) MwmApplication.get().getSystemService(Context.LOCATION_SERVICE);
|
||||
return findBestNotExpiredLocation(manager,
|
||||
filterProviders(manager),
|
||||
expirationMillis);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Location findBestNotExpiredLocation(LocationManager manager, List<String> providers, long expirationMillis)
|
||||
{
|
||||
Location res = null;
|
||||
for (final String pr : providers)
|
||||
{
|
||||
final Location l = mLocationManager.getLastKnownLocation(pr);
|
||||
if (l != null && !LocationUtils.isExpired(l, l.getTime(), expirationMs))
|
||||
{
|
||||
if (res == null || res.getAccuracy() > l.getAccuracy())
|
||||
res = l;
|
||||
}
|
||||
final Location last = manager.getLastKnownLocation(pr);
|
||||
if (last == null || LocationUtils.isExpired(last, last.getTime(), expirationMillis))
|
||||
continue;
|
||||
|
||||
if (res == null || res.getAccuracy() > last.getAccuracy())
|
||||
res = last;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
List<String> filterProviders()
|
||||
@NonNull
|
||||
public static List<String> filterProviders(LocationManager locationManager)
|
||||
{
|
||||
List<String> allProviders = mLocationManager.getProviders(false);
|
||||
List<String> res = new ArrayList<>(allProviders.size());
|
||||
|
||||
for (final String provider : allProviders)
|
||||
{
|
||||
if (LocationManager.PASSIVE_PROVIDER.equals(provider))
|
||||
continue;
|
||||
|
||||
if (mLocationManager.isProviderEnabled(provider))
|
||||
res.add(provider);
|
||||
}
|
||||
|
||||
final List<String> res = locationManager.getProviders(true /* enabledOnly */);
|
||||
res.remove(LocationManager.PASSIVE_PROVIDER);
|
||||
return res;
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ package com.mapswithme.maps.location;
|
|||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.mapswithme.util.LocationUtils;
|
||||
import com.mapswithme.util.log.Logger;
|
||||
|
@ -21,7 +22,7 @@ abstract class BaseLocationProvider implements LocationListener
|
|||
return (newLocation.getAccuracy() < lastAccuracy);
|
||||
}
|
||||
|
||||
final boolean isLocationBetterThanLast(Location newLocation)
|
||||
final boolean isLocationBetterThanLast(@Nullable Location newLocation)
|
||||
{
|
||||
if (newLocation == null)
|
||||
return false;
|
||||
|
@ -62,6 +63,9 @@ abstract class BaseLocationProvider implements LocationListener
|
|||
sLogger.d("Status changed for location provider: ", provider, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether location polling was started successfully.
|
||||
*/
|
||||
protected abstract boolean start();
|
||||
protected abstract void stop();
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ class GoogleFusedLocationProvider extends BaseLocationProvider
|
|||
@Override
|
||||
protected boolean start()
|
||||
{
|
||||
if (mGoogleApiClient == null || mGoogleApiClient.isConnected() || mGoogleApiClient.isConnecting())
|
||||
if (mGoogleApiClient.isConnected() || mGoogleApiClient.isConnecting())
|
||||
return true;
|
||||
|
||||
mLocationRequest = LocationRequest.create();
|
||||
|
@ -65,9 +65,6 @@ class GoogleFusedLocationProvider extends BaseLocationProvider
|
|||
@Override
|
||||
protected void stop()
|
||||
{
|
||||
if (mGoogleApiClient == null)
|
||||
return;
|
||||
|
||||
if (mGoogleApiClient.isConnected())
|
||||
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@ import android.app.Activity;
|
|||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.location.Location;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
import com.google.android.gms.common.GoogleApiAvailability;
|
||||
|
@ -46,7 +46,6 @@ public enum LocationHelper
|
|||
private static final long INTERVAL_NAVIGATION_BICYCLE_MS = 1000;
|
||||
private static final long INTERVAL_NAVIGATION_PEDESTRIAN_MS = 1000;
|
||||
|
||||
|
||||
private static final long STOP_DELAY_MS = 5000;
|
||||
static final int REQUEST_RESOLVE_ERROR = 101;
|
||||
|
||||
|
@ -54,8 +53,8 @@ public enum LocationHelper
|
|||
{
|
||||
Activity getActivity();
|
||||
void onMyPositionModeChanged(int newMode);
|
||||
void onLocationUpdated(Location location);
|
||||
void onCompassUpdated(CompassData compass);
|
||||
void onLocationUpdated(@NonNull Location location);
|
||||
void onCompassUpdated(@NonNull CompassData compass);
|
||||
boolean shouldNotifyLocationNotFound();
|
||||
}
|
||||
|
||||
|
@ -131,10 +130,11 @@ public enum LocationHelper
|
|||
private boolean mActive;
|
||||
private boolean mLocationStopped;
|
||||
private boolean mColdStart = true;
|
||||
private boolean mPendingNoLocation;
|
||||
|
||||
private Location mSavedLocation;
|
||||
private MapObject mMyPosition;
|
||||
private long mLastLocationTime;
|
||||
private long mSavedLocationTime;
|
||||
|
||||
private final SensorHelper mSensorHelper = new SensorHelper();
|
||||
private BaseLocationProvider mLocationProvider;
|
||||
|
@ -146,7 +146,6 @@ public enum LocationHelper
|
|||
private boolean mHighAccuracy;
|
||||
private CompassData mCompassData;
|
||||
|
||||
private boolean mPendingNoLocation;
|
||||
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private final LocationState.ModeChangeListener mModeChangeListener = new LocationState.ModeChangeListener()
|
||||
|
@ -235,14 +234,17 @@ public enum LocationHelper
|
|||
startInternal();
|
||||
}
|
||||
|
||||
public void onLocationUpdated(Location location)
|
||||
public void onLocationUpdated(@NonNull Location location)
|
||||
{
|
||||
mSavedLocation = location;
|
||||
mMyPosition = null;
|
||||
mLastLocationTime = System.currentTimeMillis();
|
||||
mSavedLocationTime = System.currentTimeMillis();
|
||||
notifyLocationUpdated();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MapObject.MY_POSITION, null if location is not yet determined or "My position" button is switched off.
|
||||
*/
|
||||
@Nullable
|
||||
public MapObject getMyPosition()
|
||||
{
|
||||
|
@ -266,9 +268,10 @@ public enum LocationHelper
|
|||
* <p>If you need the location regardless of the button's state, use {@link #getLastKnownLocation()}.
|
||||
* @return {@code null} if no location is saved or "My position" button is in "No follow, no position" mode.
|
||||
*/
|
||||
@Nullable
|
||||
public Location getSavedLocation() { return mSavedLocation; }
|
||||
|
||||
public long getSavedLocationTime() { return mLastLocationTime; }
|
||||
public long getSavedLocationTime() { return mSavedLocationTime; }
|
||||
|
||||
void notifyCompassUpdated(long time, double magneticNorth, double trueNorth, double accuracy)
|
||||
{
|
||||
|
@ -350,7 +353,7 @@ public enum LocationHelper
|
|||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
mLocationStopped = false;
|
||||
onMyPositionButtonClicked();
|
||||
LocationState.nativeSwitchToNextMode();
|
||||
}
|
||||
}).setOnDismissListener(new DialogInterface.OnDismissListener()
|
||||
{
|
||||
|
@ -394,7 +397,7 @@ public enum LocationHelper
|
|||
mLogger.d("onActivityResult(): success: " + !mLocationStopped);
|
||||
|
||||
if (!mLocationStopped)
|
||||
onMyPositionButtonClicked();
|
||||
LocationState.nativeSwitchToNextMode();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -611,6 +614,23 @@ public enum LocationHelper
|
|||
}
|
||||
|
||||
mUiCallback = callback;
|
||||
compareWithPreviousCallback();
|
||||
|
||||
Utils.keepScreenOn(true, mUiCallback.getActivity().getWindow());
|
||||
|
||||
mUiCallback.onMyPositionModeChanged(LocationState.getMode());
|
||||
if (mCompassData != null)
|
||||
mUiCallback.onCompassUpdated(mCompassData);
|
||||
|
||||
if (hasPendingNoLocation())
|
||||
notifyLocationNotFound();
|
||||
|
||||
if (!mLocationStopped)
|
||||
addListener(mLocationListener, true);
|
||||
}
|
||||
|
||||
private void compareWithPreviousCallback()
|
||||
{
|
||||
if (mPrevUiCallback != null)
|
||||
{
|
||||
UiCallback prev = mPrevUiCallback.get();
|
||||
|
@ -620,21 +640,7 @@ public enum LocationHelper
|
|||
setHasPendingNoLocation(false);
|
||||
}
|
||||
}
|
||||
|
||||
Utils.keepScreenOn(true, mUiCallback.getActivity().getWindow());
|
||||
|
||||
int mode = LocationState.getMode();
|
||||
mUiCallback.onMyPositionModeChanged(mode);
|
||||
if (mCompassData != null)
|
||||
mUiCallback.onCompassUpdated(mCompassData);
|
||||
|
||||
mPrevUiCallback = new WeakReference<>(mUiCallback);
|
||||
|
||||
if (hasPendingNoLocation())
|
||||
notifyLocationNotFound();
|
||||
|
||||
if (!mLocationStopped)
|
||||
addListener(mLocationListener, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -655,57 +661,33 @@ public enum LocationHelper
|
|||
removeListener(mLocationListener, delayed);
|
||||
}
|
||||
|
||||
public void onMyPositionButtonClicked()
|
||||
{
|
||||
int mode = LocationState.getMode();
|
||||
mLogger.d("onMyPositionButtonClicked(). Mode was: " + LocationState.nameOf(mode));
|
||||
|
||||
if (mode == LocationState.PENDING_POSITION)
|
||||
{
|
||||
mLogger.d("Pending. Skip");
|
||||
return;
|
||||
}
|
||||
|
||||
mLocationStopped = false;
|
||||
LocationState.nativeSwitchToNextMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains last known location regardless of "My position" button state.
|
||||
* @return {@code null} on failure.
|
||||
*/
|
||||
public @Nullable Location getLastKnownLocation(long expirationMs)
|
||||
@Nullable
|
||||
public Location getLastKnownLocation(long expirationMillis)
|
||||
{
|
||||
if (mSavedLocation != null)
|
||||
return mSavedLocation;
|
||||
|
||||
AndroidNativeProvider provider = new AndroidNativeProvider()
|
||||
{
|
||||
@Override
|
||||
public void onLocationChanged(Location location)
|
||||
{
|
||||
// Block ancestor
|
||||
}
|
||||
};
|
||||
|
||||
List<String> providers = provider.filterProviders();
|
||||
if (providers.isEmpty())
|
||||
return null;
|
||||
|
||||
return provider.findBestNotExpiredLocation(providers, expirationMs);
|
||||
return AndroidNativeProvider.findBestNotExpiredLocation(expirationMillis);
|
||||
}
|
||||
|
||||
public @Nullable Location getLastKnownLocation()
|
||||
@Nullable
|
||||
public Location getLastKnownLocation()
|
||||
{
|
||||
return getLastKnownLocation(LocationUtils.LOCATION_EXPIRATION_TIME_MILLIS_LONG);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CompassData getCompassData()
|
||||
{
|
||||
return mCompassData;
|
||||
}
|
||||
|
||||
private static native void nativeOnLocationError(int errorCode);
|
||||
private static native void nativeLocationUpdated(long time, double lat, double lon, float accuracy, double altitude, float speed, float bearing);
|
||||
private static native void nativeLocationUpdated(long time, double lat, double lon, float accuracy,
|
||||
double altitude, float speed, float bearing);
|
||||
static native float[] nativeUpdateCompassSensor(int ind, float[] arr);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import android.widget.ImageView;
|
|||
|
||||
import com.mapswithme.maps.LocationState;
|
||||
import com.mapswithme.maps.R;
|
||||
import com.mapswithme.maps.location.LocationHelper;
|
||||
import com.mapswithme.util.Graphics;
|
||||
import com.mapswithme.util.ThemeUtils;
|
||||
import com.mapswithme.util.statistics.AlohaHelper;
|
||||
|
@ -27,8 +26,7 @@ public class MyPositionButton
|
|||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
LocationHelper.INSTANCE.onMyPositionButtonClicked();
|
||||
|
||||
LocationState.nativeSwitchToNextMode();
|
||||
Statistics.INSTANCE.trackEvent(Statistics.EventName.TOOLBAR_MY_POSITION);
|
||||
AlohaHelper.logClick(AlohaHelper.TOOLBAR_MY_POSITION);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue