@Override void updateLatLng(@NonNull Location location) { if (latLng == null) { // first location fix latLng = new LatLng(location); locationUpdateTimestamp = SystemClock.elapsedRealtime(); } // updateLatLng timestamp long previousUpdateTimeStamp = locationUpdateTimestamp; locationUpdateTimestamp = SystemClock.elapsedRealtime(); // calculate animation duration long locationUpdateDuration; if (previousUpdateTimeStamp == 0) { locationUpdateDuration = 0; } else { // TODO remove 10 * hack to multiply duration to workaround easing interpolation // (easeCamera) locationUpdateDuration = 10 * (locationUpdateTimestamp - previousUpdateTimeStamp); } // calculate interpolated location previousLocation = latLng; latLng = new LatLng(location); interpolatedLocation = new LatLng( (latLng.getLatitude() + previousLocation.getLatitude()) / 2, (latLng.getLongitude() + previousLocation.getLongitude()) / 2); // build new camera CameraPosition.Builder builder = new CameraPosition.Builder().target(interpolatedLocation); // add direction if (myBearingTrackingMode == MyBearingTracking.GPS) { if (location.hasBearing()) { builder.bearing(location.getBearing()); gpsDirection = 0; } } else if (myBearingTrackingMode == MyBearingTracking.COMPASS) { if (!compassListener.isPaused()) { builder.bearing(compassListener.getCurrentDegree()); compassDirection = 0; } } updateAccuracy(location); // animate to new camera mapboxMap.easeCamera( CameraUpdateFactory.newCameraPosition(builder.build()), (int) locationUpdateDuration, null); }