diff --git a/app/src/main/java/org/y20k/trackbook/MainActivity.java b/app/src/main/java/org/y20k/trackbook/MainActivity.java index 2334319..01cfda9 100644 --- a/app/src/main/java/org/y20k/trackbook/MainActivity.java +++ b/app/src/main/java/org/y20k/trackbook/MainActivity.java @@ -55,7 +55,6 @@ import android.widget.Button; import android.widget.Toast; import org.osmdroid.config.Configuration; -import org.y20k.trackbook.core.Track; import org.y20k.trackbook.helpers.DialogHelper; import org.y20k.trackbook.helpers.LogHelper; import org.y20k.trackbook.helpers.NightModeHelper; @@ -310,10 +309,10 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys { /* Resume recording movements */ - private void resumeRecording() { + private void resumeRecording(Location lastLocation) { startTrackerService(); if (mBound) { - mTrackerService.resumeTracking(); + mTrackerService.resumeTracking(lastLocation); } } @@ -378,14 +377,20 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys { /* Handles tap on the button "resume" */ private void handleResumeButtonClick(View view) { - // show snackbar - Snackbar.make(view, R.string.snackbar_message_tracking_resumed, Snackbar.LENGTH_SHORT).setAction("Action", null).show(); + // get last location from MainActivity Fragment // todo check -> may produce NullPointerException + MainActivityMapFragment mainActivityMapFragment = (MainActivityMapFragment) mSectionsPagerAdapter.getFragment(FRAGMENT_ID_MAP); + Location lastLocation = mainActivityMapFragment.getCurrentBestLocation(); - // resume tracking - resumeRecording(); - - // hide sub menu - showFloatingActionButtonMenu(false); + if (lastLocation != null) { + // show snackbar + Snackbar.make(view, R.string.snackbar_message_tracking_resumed, Snackbar.LENGTH_SHORT).setAction("Action", null).show(); + // resume tracking + resumeRecording(lastLocation); + // hide sub menu + showFloatingActionButtonMenu(false); + } else { + Toast.makeText(this, getString(R.string.toast_message_location_services_not_ready), Toast.LENGTH_LONG).show(); + } } @@ -538,21 +543,12 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys { Location lastLocation = mainActivityMapFragment.getCurrentBestLocation(); if (lastLocation != null) { - // change state - mTrackerServiceRunning = true; - mFloatingActionButtonState = FAB_STATE_RECORDING; - setFloatingActionButtonState(); - // show snackbar Snackbar.make(view, R.string.snackbar_message_tracking_started, Snackbar.LENGTH_SHORT).setAction("Action", null).show(); - - // start tracker service + // start recording startRecording(lastLocation); - } else { Toast.makeText(this, getString(R.string.toast_message_location_services_not_ready), Toast.LENGTH_LONG).show(); - // change state back - mTrackerServiceRunning = false; } break; @@ -560,10 +556,6 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys { case FAB_STATE_RECORDING: // show snackbar Snackbar.make(view, R.string.snackbar_message_tracking_stopped, Snackbar.LENGTH_SHORT).setAction("Action", null).show(); - - // change state - // --> is handled by broadcast receiver - // stop tracker service stopRecording(); diff --git a/app/src/main/java/org/y20k/trackbook/TrackerService.java b/app/src/main/java/org/y20k/trackbook/TrackerService.java index 3524e4f..0cf3663 100644 --- a/app/src/main/java/org/y20k/trackbook/TrackerService.java +++ b/app/src/main/java/org/y20k/trackbook/TrackerService.java @@ -42,7 +42,6 @@ import android.support.v4.content.LocalBroadcastManager; import android.widget.Toast; import org.y20k.trackbook.core.Track; -import org.y20k.trackbook.core.WayPoint; import org.y20k.trackbook.helpers.LocationHelper; import org.y20k.trackbook.helpers.LogHelper; import org.y20k.trackbook.helpers.NotificationHelper; @@ -78,6 +77,7 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven private NotificationManager mNotificationManager; private boolean mTrackerServiceRunning; private boolean mLocationSystemSetting; + private boolean mResumedFlag; private final IBinder mBinder = new LocalBinder(); // todo move to onCreate @@ -101,6 +101,9 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven // create content observer for changes in System Settings mSettingsContentObserver = new SettingsContentObserver(new Handler()); + + // initialize the resume flag + mResumedFlag = false; } @@ -133,7 +136,7 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven } // ACTION RESUME else if (ACTION_RESUME.equals(intent.getAction())) { - resumeTracking(); + resumeTracking(LocationHelper.determineLastKnownLocation(mLocationManager)); } // START_STICKY is used for services that are explicitly started and stopped as needed @@ -192,9 +195,6 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager); } - // initialize step counter - mStepCountOffset = 0; - // begin recording startMovementRecording(); @@ -206,10 +206,13 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven /* Resume tracking after stop/pause */ - public void resumeTracking() { + public void resumeTracking(Location lastLocation) { if (mLocationSystemSetting) { LogHelper.v(LOG_TAG, "Recording resumed"); + // switch the resume flag + mResumedFlag = true; + // create a new track - if requested StorageHelper storageHelper = new StorageHelper(this); if (storageHelper.tempFileExists()) { @@ -227,15 +230,12 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven } // get last location - if (mTrack.getSize() > 0) { + mCurrentBestLocation = lastLocation; + // FALLBACK: use last recorded location + if (mCurrentBestLocation == null && mTrack.getSize() > 0) { mCurrentBestLocation = mTrack.getWayPointLocation(mTrack.getSize() -1); - } else { - mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager); } - // initialize step counter - mStepCountOffset = mTrack.getStepCount(); - // begin recording startMovementRecording(); @@ -297,6 +297,9 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven /* Starts to record movements */ private void startMovementRecording() { + // initialize step counter + mStepCountOffset = 0; + // add last location as WayPoint to track addWayPointToTrack(); @@ -322,8 +325,7 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven /* Registers a step counter listener */ private void startStepCounter() { - boolean stepCounterAvailable; - stepCounterAvailable = mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(TYPE_STEP_COUNTER), SensorManager.SENSOR_DELAY_UI); + boolean stepCounterAvailable = mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(TYPE_STEP_COUNTER), SensorManager.SENSOR_DELAY_UI); if (stepCounterAvailable) { LogHelper.v(LOG_TAG, "Pedometer sensor available: Registering listener."); } else { @@ -373,38 +375,47 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven /* Adds a new WayPoint to current track */ private void addWayPointToTrack() { - // create new WayPoint - WayPoint newWayPoint = null; - - // get number of previously tracked WayPoints + boolean success = false; + Location previousLocation = null; int trackSize = mTrack.getWayPoints().size(); if (trackSize == 0) { // add first location to track - newWayPoint = mTrack.addWayPoint(mCurrentBestLocation); + success = mTrack.addWayPoint(previousLocation, mCurrentBestLocation); + } else { - // get last WayPoint and compare it to current location - Location lastWayPoint = mTrack.getWayPointLocation(trackSize - 1); + // get location of previous WayPoint + previousLocation = mTrack.getWayPointLocation(trackSize - 1); // default value for average speed float averageSpeed = 0f; - // compute average speed if new location come from network provider + // compute average speed if new location came from network provider if (trackSize > 1 && mCurrentBestLocation.getProvider().equals(LocationManager.NETWORK_PROVIDER)) { Location firstWayPoint = mTrack.getWayPointLocation(0); - float distance = firstWayPoint.distanceTo(lastWayPoint); - long timeDifference = lastWayPoint.getElapsedRealtimeNanos() - firstWayPoint.getElapsedRealtimeNanos(); + float distance = firstWayPoint.distanceTo(previousLocation); + long timeDifference = previousLocation.getElapsedRealtimeNanos() - firstWayPoint.getElapsedRealtimeNanos(); averageSpeed = distance / ((float) timeDifference / ONE_SECOND_IN_NANOSECOND); } - if (LocationHelper.isNewWayPoint(lastWayPoint, mCurrentBestLocation, averageSpeed)) { + if (LocationHelper.isNewWayPoint(previousLocation, mCurrentBestLocation, averageSpeed)) { // if new, add current best location to track - newWayPoint = mTrack.addWayPoint(mCurrentBestLocation); + success = mTrack.addWayPoint(previousLocation, mCurrentBestLocation); } } - // send local broadcast if new WayPoint added - if (newWayPoint != null) { + if (success) { + if (mResumedFlag) { + // mark last location as stop over + int lastWayPoint = mTrack.getWayPoints().size() - 2; + mTrack.getWayPoints().get(lastWayPoint).setIsStopOver(true); + mResumedFlag = false; + } else { + // update distance, if not resumed + mTrack.updateDistance(previousLocation, mCurrentBestLocation); + } + + // send local broadcast if new WayPoint was added broadcastTrackUpdate(); } diff --git a/app/src/main/java/org/y20k/trackbook/core/Track.java b/app/src/main/java/org/y20k/trackbook/core/Track.java index fd64700..07835c3 100644 --- a/app/src/main/java/org/y20k/trackbook/core/Track.java +++ b/app/src/main/java/org/y20k/trackbook/core/Track.java @@ -19,9 +19,9 @@ package org.y20k.trackbook.core; import android.location.Location; import android.os.Parcel; import android.os.Parcelable; +import android.support.annotation.Nullable; import org.y20k.trackbook.helpers.LocationHelper; -import org.y20k.trackbook.helpers.LogHelper; import org.y20k.trackbook.helpers.TrackbookKeys; import java.util.ArrayList; @@ -124,36 +124,46 @@ public class Track implements TrackbookKeys, Parcelable { /* Adds new WayPoint */ - public WayPoint addWayPoint(Location location) { - // add up distance - mTrackLength = addDistanceToTrack(location); + public boolean addWayPoint(@Nullable Location previousLocation, Location newLocation) { - int wayPointCount = mWayPoints.size(); - - // determine if last WayPoint was a stopover - boolean stopOver = false; - if (wayPointCount > 1) { - Location lastLocation = mWayPoints.get(wayPointCount - 1).getLocation(); - stopOver = LocationHelper.isStopOver(lastLocation, location); - } - if (stopOver) { - // mark last WayPoint as stopover - LogHelper.v(LOG_TAG, "Last Location was a stop."); - mWayPoints.get(wayPointCount-1).setIsStopOver(true); + // toggle stop over status, if necessary + boolean isStopOver = LocationHelper.isStopOver(previousLocation, newLocation); + if (isStopOver) { + int wayPointCount = mWayPoints.size(); + mWayPoints.get(wayPointCount-1).setIsStopOver(isStopOver); } // create new WayPoint - WayPoint wayPoint = new WayPoint(location, false, mTrackLength); + WayPoint wayPoint = new WayPoint(newLocation, false, mTrackLength); // add new WayPoint to track - mWayPoints.add(wayPoint); + return mWayPoints.add(wayPoint); + } - return wayPoint; + + /* Updates distance */ + public boolean updateDistance(@Nullable Location previousLocation, Location newLocation){ + // two data points needed to calculate distance + if (previousLocation != null) { + // add up distance + mTrackLength = mTrackLength + previousLocation.distanceTo(newLocation); + return true; + } else { + // this was the first waypoint + return false; + } + } + + + /* Toggles stop over status of last waypoint */ + public void toggleLastWayPointStopOverStatus(boolean stopOver) { + int wayPointCount = mWayPoints.size(); + mWayPoints.get(wayPointCount-1).setIsStopOver(stopOver); } /* Sets end time and date of recording */ - public void setRecordingEnd () { + public void setRecordingEnd() { mRecordingStop = GregorianCalendar.getInstance().getTime(); } @@ -308,20 +318,20 @@ public class Track implements TrackbookKeys, Parcelable { } - /* Adds distance to given location to length of track */ - private float addDistanceToTrack(Location location) { - // get number of previously recorded WayPoints - int wayPointCount = mWayPoints.size(); - - // at least two data points are needed - if (wayPointCount >= 1) { - // add up distance - Location lastLocation = mWayPoints.get(wayPointCount - 1).getLocation(); - return mTrackLength + lastLocation.distanceTo(location); - } - - return 0f; - } +// /* Adds distance to given location to length of track */ +// private float addDistanceToTrack(Location location) { +// // get number of previously recorded WayPoints +// int wayPointCount = mWayPoints.size(); +// +// // at least two data points are needed +// if (wayPointCount >= 1) { +// // add up distance +// Location lastLocation = mWayPoints.get(wayPointCount - 1).getLocation(); +// return mTrackLength + lastLocation.distanceTo(location); +// } +// +// return 0f; +// } /* Converts a given distance value to a readable string */ diff --git a/app/src/main/java/org/y20k/trackbook/helpers/LocationHelper.java b/app/src/main/java/org/y20k/trackbook/helpers/LocationHelper.java index 9c55493..5f0041f 100644 --- a/app/src/main/java/org/y20k/trackbook/helpers/LocationHelper.java +++ b/app/src/main/java/org/y20k/trackbook/helpers/LocationHelper.java @@ -22,6 +22,7 @@ import android.location.LocationListener; import android.location.LocationManager; import android.os.SystemClock; import android.provider.Settings; +import android.support.annotation.Nullable; import java.util.List; import java.util.Locale; @@ -174,9 +175,13 @@ public final class LocationHelper implements TrackbookKeys { /* Checks if given location is a stop over */ - public static boolean isStopOver(Location lastLocation, Location newLocation) { - long timeDifference = newLocation.getElapsedRealtimeNanos() - lastLocation.getElapsedRealtimeNanos(); - return timeDifference >= FIVE_MINUTES_IN_NANOSECONDS; + public static boolean isStopOver(@Nullable Location previousLocation, Location newLocation) { + if (previousLocation != null) { + long timeDifference = newLocation.getElapsedRealtimeNanos() - previousLocation.getElapsedRealtimeNanos(); + return timeDifference >= FIVE_MINUTES_IN_NANOSECONDS; + } else { + return false; + } }