[android] Grey out GPS marker when location is stale

Fixes #2694
This commit is contained in:
Leith Bade
2015-10-28 14:10:19 +11:00
parent a67645cb39
commit a2ac435171
2 changed files with 45 additions and 19 deletions

View File

@@ -13,6 +13,8 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Build;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
@@ -38,6 +40,7 @@ final class UserLocationView extends View {
private boolean mShowMarker;
private boolean mShowDirection;
private boolean mShowAccuracy;
private boolean mStaleMarker;
private PointF mMarkerScreenPoint;
private Matrix mMarkerScreenMatrix;
@@ -191,19 +194,17 @@ final class UserLocationView extends View {
canvas.concat(mMarkerScreenMatrix);
Drawable dotDrawable = mShowDirection ? mUserLocationBearingDrawable : mUserLocationDrawable;
// IMPORTANT also update in uodate()
dotDrawable = mStaleMarker ? mUserLocationStaleDrawable : dotDrawable;
// IMPORTANT also update in update()
RectF dotBounds = mShowDirection ? mUserLocationBearingDrawableBoundsF : mUserLocationDrawableBoundsF;
dotBounds = mStaleMarker ? mUserLocationStaleDrawableBoundsF : dotBounds;
boolean willDraw;
willDraw = mShowAccuracy && !canvas.quickReject(mAccuracyPath, Canvas.EdgeType.AA);
boolean willDraw =
mShowAccuracy && !mStaleMarker && !canvas.quickReject(mAccuracyPath, Canvas.EdgeType.AA);
willDraw |= !canvas.quickReject(dotBounds, Canvas.EdgeType.AA);
dotBounds.offset(
(int) -mMarkerScreenPoint.x,
(int) -mMarkerScreenPoint.y);
if (willDraw) {
if (mShowAccuracy) {
if (mShowAccuracy && !mStaleMarker) {
canvas.drawPath(mAccuracyPath, mAccuracyPaintFill);
canvas.drawPath(mAccuracyPath, mAccuracyPaintStroke);
}
@@ -236,6 +237,8 @@ final class UserLocationView extends View {
if (isEnabled() && mShowMarker) {
setVisibility(View.VISIBLE);
mStaleMarker = isStale(mUserLocation);
// compute new marker position
// TODO add JNI method that takes existing pointf
mMarkerScreenPoint = mMapView.toScreenLocation(mMarkerCoordinate);
@@ -251,7 +254,7 @@ final class UserLocationView extends View {
}
// adjust accuracy circle
if (mShowAccuracy) {
if (mShowAccuracy && !mStaleMarker) {
mAccuracyPath.reset();
mAccuracyPath.addCircle(0.0f, 0.0f,
(float) (mMarkerAccuracy / mMapView.getMetersPerPixelAtLatitude(
@@ -272,7 +275,9 @@ final class UserLocationView extends View {
}
RectF dotBounds = mShowDirection ? mUserLocationBearingDrawableBoundsF : mUserLocationDrawableBoundsF;
RectF largerBounds = mAccuracyBounds.contains(dotBounds) ? mAccuracyBounds : dotBounds;
dotBounds = mStaleMarker ? mUserLocationStaleDrawableBoundsF : dotBounds;
RectF largerBounds = mShowAccuracy && !mStaleMarker && mAccuracyBounds.contains(dotBounds)
? mAccuracyBounds : dotBounds;
mMarkerScreenMatrix.mapRect(mDirtyRectF, largerBounds);
mDirtyRectF.roundOut(mDirtyRect);
invalidate(mDirtyRect); // the new marker location
@@ -299,7 +304,10 @@ final class UserLocationView extends View {
if (!mLocationClient.isConnected()) {
mUserLocation = null;
mLocationClient.connect();
setLocation(LocationServices.FusedLocationApi.getLastLocation());
Location lastLocation = LocationServices.FusedLocationApi.getLastLocation();
if (lastLocation != null) {
setLocation(lastLocation);
}
mLocationListener = new MyLocationListener();
LocationServices.FusedLocationApi.requestLocationUpdates(mLocationRequest, mLocationListener);
}
@@ -323,6 +331,22 @@ final class UserLocationView extends View {
}
}
private boolean isStale(Location location) {
if (location != null) {
long ageInNanos;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
ageInNanos = SystemClock.elapsedRealtimeNanos() -
location.getElapsedRealtimeNanos();
} else {
ageInNanos = (System.currentTimeMillis() - location.getTime()) * 1000 * 1000;
}
final long oneMinuteInNanos = 60L * 1000 * 1000 * 1000;
return ageInNanos > oneMinuteInNanos;
} else {
return false;
}
}
// Handles location updates from GPS
private void setLocation(Location location) {
// if null we should hide the marker

View File

@@ -72,7 +72,6 @@ public class MainActivity extends AppCompatActivity {
// Used for Annotations
private boolean mIsAnnotationsOn = false;
private static final DecimalFormat latLngFormatter = new DecimalFormat("#.#####");
//
@@ -179,13 +178,6 @@ public class MainActivity extends AppCompatActivity {
public void onClick(View v) {
// Toggle GPS position updates
toggleGps(!mMapView.isMyLocationEnabled());
if (mMapView.isMyLocationEnabled()) {
Location location = mMapView.getMyLocation();
if (location != null) {
mMapView.setZoomLevel(18);
mMapView.setCenterCoordinate(new LatLng(location));
}
}
}
});
@@ -425,6 +417,16 @@ public class MainActivity extends AppCompatActivity {
}
private void enableGps() {
mMapView.setOnMyLocationChangeListener(new MapView.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange(@Nullable Location location) {
if (location != null) {
mMapView.setZoomLevel(16);
mMapView.setCenterCoordinate(new LatLng(location));
mMapView.setOnMyLocationChangeListener(null);
}
}
});
mMapView.setMyLocationEnabled(true);
mLocationFAB.setColorFilter(ContextCompat.getColor(this, R.color.primary));
}