squashed some bugs in the resume feature

This commit is contained in:
y20k 2018-04-10 17:45:43 +02:00
parent dd13d1f462
commit 71a8d4c950
4 changed files with 107 additions and 89 deletions

View file

@ -55,7 +55,6 @@ import android.widget.Button;
import android.widget.Toast; import android.widget.Toast;
import org.osmdroid.config.Configuration; import org.osmdroid.config.Configuration;
import org.y20k.trackbook.core.Track;
import org.y20k.trackbook.helpers.DialogHelper; import org.y20k.trackbook.helpers.DialogHelper;
import org.y20k.trackbook.helpers.LogHelper; import org.y20k.trackbook.helpers.LogHelper;
import org.y20k.trackbook.helpers.NightModeHelper; import org.y20k.trackbook.helpers.NightModeHelper;
@ -310,10 +309,10 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
/* Resume recording movements */ /* Resume recording movements */
private void resumeRecording() { private void resumeRecording(Location lastLocation) {
startTrackerService(); startTrackerService();
if (mBound) { if (mBound) {
mTrackerService.resumeTracking(); mTrackerService.resumeTracking(lastLocation);
} }
} }
@ -378,14 +377,20 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
/* Handles tap on the button "resume" */ /* Handles tap on the button "resume" */
private void handleResumeButtonClick(View view) { private void handleResumeButtonClick(View view) {
// show snackbar // get last location from MainActivity Fragment // todo check -> may produce NullPointerException
Snackbar.make(view, R.string.snackbar_message_tracking_resumed, Snackbar.LENGTH_SHORT).setAction("Action", null).show(); MainActivityMapFragment mainActivityMapFragment = (MainActivityMapFragment) mSectionsPagerAdapter.getFragment(FRAGMENT_ID_MAP);
Location lastLocation = mainActivityMapFragment.getCurrentBestLocation();
// resume tracking if (lastLocation != null) {
resumeRecording(); // show snackbar
Snackbar.make(view, R.string.snackbar_message_tracking_resumed, Snackbar.LENGTH_SHORT).setAction("Action", null).show();
// hide sub menu // resume tracking
showFloatingActionButtonMenu(false); 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(); Location lastLocation = mainActivityMapFragment.getCurrentBestLocation();
if (lastLocation != null) { if (lastLocation != null) {
// change state
mTrackerServiceRunning = true;
mFloatingActionButtonState = FAB_STATE_RECORDING;
setFloatingActionButtonState();
// show snackbar // show snackbar
Snackbar.make(view, R.string.snackbar_message_tracking_started, Snackbar.LENGTH_SHORT).setAction("Action", null).show(); Snackbar.make(view, R.string.snackbar_message_tracking_started, Snackbar.LENGTH_SHORT).setAction("Action", null).show();
// start recording
// start tracker service
startRecording(lastLocation); startRecording(lastLocation);
} else { } else {
Toast.makeText(this, getString(R.string.toast_message_location_services_not_ready), Toast.LENGTH_LONG).show(); Toast.makeText(this, getString(R.string.toast_message_location_services_not_ready), Toast.LENGTH_LONG).show();
// change state back
mTrackerServiceRunning = false;
} }
break; break;
@ -560,10 +556,6 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
case FAB_STATE_RECORDING: case FAB_STATE_RECORDING:
// show snackbar // show snackbar
Snackbar.make(view, R.string.snackbar_message_tracking_stopped, Snackbar.LENGTH_SHORT).setAction("Action", null).show(); 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 // stop tracker service
stopRecording(); stopRecording();

View file

@ -42,7 +42,6 @@ import android.support.v4.content.LocalBroadcastManager;
import android.widget.Toast; import android.widget.Toast;
import org.y20k.trackbook.core.Track; import org.y20k.trackbook.core.Track;
import org.y20k.trackbook.core.WayPoint;
import org.y20k.trackbook.helpers.LocationHelper; import org.y20k.trackbook.helpers.LocationHelper;
import org.y20k.trackbook.helpers.LogHelper; import org.y20k.trackbook.helpers.LogHelper;
import org.y20k.trackbook.helpers.NotificationHelper; import org.y20k.trackbook.helpers.NotificationHelper;
@ -78,6 +77,7 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
private NotificationManager mNotificationManager; private NotificationManager mNotificationManager;
private boolean mTrackerServiceRunning; private boolean mTrackerServiceRunning;
private boolean mLocationSystemSetting; private boolean mLocationSystemSetting;
private boolean mResumedFlag;
private final IBinder mBinder = new LocalBinder(); // todo move to onCreate 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 // create content observer for changes in System Settings
mSettingsContentObserver = new SettingsContentObserver(new Handler()); 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 // ACTION RESUME
else if (ACTION_RESUME.equals(intent.getAction())) { 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 // 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); mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager);
} }
// initialize step counter
mStepCountOffset = 0;
// begin recording // begin recording
startMovementRecording(); startMovementRecording();
@ -206,10 +206,13 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
/* Resume tracking after stop/pause */ /* Resume tracking after stop/pause */
public void resumeTracking() { public void resumeTracking(Location lastLocation) {
if (mLocationSystemSetting) { if (mLocationSystemSetting) {
LogHelper.v(LOG_TAG, "Recording resumed"); LogHelper.v(LOG_TAG, "Recording resumed");
// switch the resume flag
mResumedFlag = true;
// create a new track - if requested // create a new track - if requested
StorageHelper storageHelper = new StorageHelper(this); StorageHelper storageHelper = new StorageHelper(this);
if (storageHelper.tempFileExists()) { if (storageHelper.tempFileExists()) {
@ -227,15 +230,12 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
} }
// get last location // 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); mCurrentBestLocation = mTrack.getWayPointLocation(mTrack.getSize() -1);
} else {
mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager);
} }
// initialize step counter
mStepCountOffset = mTrack.getStepCount();
// begin recording // begin recording
startMovementRecording(); startMovementRecording();
@ -297,6 +297,9 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
/* Starts to record movements */ /* Starts to record movements */
private void startMovementRecording() { private void startMovementRecording() {
// initialize step counter
mStepCountOffset = 0;
// add last location as WayPoint to track // add last location as WayPoint to track
addWayPointToTrack(); addWayPointToTrack();
@ -322,8 +325,7 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
/* Registers a step counter listener */ /* Registers a step counter listener */
private void startStepCounter() { private void startStepCounter() {
boolean stepCounterAvailable; boolean stepCounterAvailable = mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(TYPE_STEP_COUNTER), SensorManager.SENSOR_DELAY_UI);
stepCounterAvailable = mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(TYPE_STEP_COUNTER), SensorManager.SENSOR_DELAY_UI);
if (stepCounterAvailable) { if (stepCounterAvailable) {
LogHelper.v(LOG_TAG, "Pedometer sensor available: Registering listener."); LogHelper.v(LOG_TAG, "Pedometer sensor available: Registering listener.");
} else { } else {
@ -373,38 +375,47 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
/* Adds a new WayPoint to current track */ /* Adds a new WayPoint to current track */
private void addWayPointToTrack() { private void addWayPointToTrack() {
// create new WayPoint boolean success = false;
WayPoint newWayPoint = null; Location previousLocation = null;
// get number of previously tracked WayPoints
int trackSize = mTrack.getWayPoints().size(); int trackSize = mTrack.getWayPoints().size();
if (trackSize == 0) { if (trackSize == 0) {
// add first location to track // add first location to track
newWayPoint = mTrack.addWayPoint(mCurrentBestLocation); success = mTrack.addWayPoint(previousLocation, mCurrentBestLocation);
} else { } else {
// get last WayPoint and compare it to current location // get location of previous WayPoint
Location lastWayPoint = mTrack.getWayPointLocation(trackSize - 1); previousLocation = mTrack.getWayPointLocation(trackSize - 1);
// default value for average speed // default value for average speed
float averageSpeed = 0f; 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)) { if (trackSize > 1 && mCurrentBestLocation.getProvider().equals(LocationManager.NETWORK_PROVIDER)) {
Location firstWayPoint = mTrack.getWayPointLocation(0); Location firstWayPoint = mTrack.getWayPointLocation(0);
float distance = firstWayPoint.distanceTo(lastWayPoint); float distance = firstWayPoint.distanceTo(previousLocation);
long timeDifference = lastWayPoint.getElapsedRealtimeNanos() - firstWayPoint.getElapsedRealtimeNanos(); long timeDifference = previousLocation.getElapsedRealtimeNanos() - firstWayPoint.getElapsedRealtimeNanos();
averageSpeed = distance / ((float) timeDifference / ONE_SECOND_IN_NANOSECOND); 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 // 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 (success) {
if (newWayPoint != null) { 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(); broadcastTrackUpdate();
} }

View file

@ -19,9 +19,9 @@ package org.y20k.trackbook.core;
import android.location.Location; import android.location.Location;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.support.annotation.Nullable;
import org.y20k.trackbook.helpers.LocationHelper; import org.y20k.trackbook.helpers.LocationHelper;
import org.y20k.trackbook.helpers.LogHelper;
import org.y20k.trackbook.helpers.TrackbookKeys; import org.y20k.trackbook.helpers.TrackbookKeys;
import java.util.ArrayList; import java.util.ArrayList;
@ -124,36 +124,46 @@ public class Track implements TrackbookKeys, Parcelable {
/* Adds new WayPoint */ /* Adds new WayPoint */
public WayPoint addWayPoint(Location location) { public boolean addWayPoint(@Nullable Location previousLocation, Location newLocation) {
// add up distance
mTrackLength = addDistanceToTrack(location);
int wayPointCount = mWayPoints.size(); // toggle stop over status, if necessary
boolean isStopOver = LocationHelper.isStopOver(previousLocation, newLocation);
// determine if last WayPoint was a stopover if (isStopOver) {
boolean stopOver = false; int wayPointCount = mWayPoints.size();
if (wayPointCount > 1) { mWayPoints.get(wayPointCount-1).setIsStopOver(isStopOver);
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);
} }
// create new WayPoint // create new WayPoint
WayPoint wayPoint = new WayPoint(location, false, mTrackLength); WayPoint wayPoint = new WayPoint(newLocation, false, mTrackLength);
// add new WayPoint to track // 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 */ /* Sets end time and date of recording */
public void setRecordingEnd () { public void setRecordingEnd() {
mRecordingStop = GregorianCalendar.getInstance().getTime(); mRecordingStop = GregorianCalendar.getInstance().getTime();
} }
@ -308,20 +318,20 @@ public class Track implements TrackbookKeys, Parcelable {
} }
/* Adds distance to given location to length of track */ // /* Adds distance to given location to length of track */
private float addDistanceToTrack(Location location) { // private float addDistanceToTrack(Location location) {
// get number of previously recorded WayPoints // // get number of previously recorded WayPoints
int wayPointCount = mWayPoints.size(); // int wayPointCount = mWayPoints.size();
//
// at least two data points are needed // // at least two data points are needed
if (wayPointCount >= 1) { // if (wayPointCount >= 1) {
// add up distance // // add up distance
Location lastLocation = mWayPoints.get(wayPointCount - 1).getLocation(); // Location lastLocation = mWayPoints.get(wayPointCount - 1).getLocation();
return mTrackLength + lastLocation.distanceTo(location); // return mTrackLength + lastLocation.distanceTo(location);
} // }
//
return 0f; // return 0f;
} // }
/* Converts a given distance value to a readable string */ /* Converts a given distance value to a readable string */

View file

@ -22,6 +22,7 @@ import android.location.LocationListener;
import android.location.LocationManager; import android.location.LocationManager;
import android.os.SystemClock; import android.os.SystemClock;
import android.provider.Settings; import android.provider.Settings;
import android.support.annotation.Nullable;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -174,9 +175,13 @@ public final class LocationHelper implements TrackbookKeys {
/* Checks if given location is a stop over */ /* Checks if given location is a stop over */
public static boolean isStopOver(Location lastLocation, Location newLocation) { public static boolean isStopOver(@Nullable Location previousLocation, Location newLocation) {
long timeDifference = newLocation.getElapsedRealtimeNanos() - lastLocation.getElapsedRealtimeNanos(); if (previousLocation != null) {
return timeDifference >= FIVE_MINUTES_IN_NANOSECONDS; long timeDifference = newLocation.getElapsedRealtimeNanos() - previousLocation.getElapsedRealtimeNanos();
return timeDifference >= FIVE_MINUTES_IN_NANOSECONDS;
} else {
return false;
}
} }