In TrackRecordingService, fix the code on detecting if a location

is already inserted in the database.
In TripStatisticsUpdater, improve total distance accuracy by
taking into account the last point in a segment.
This commit is contained in:
Jimmy Shih
2012-08-24 17:46:16 -07:00
parent 41278eb137
commit 296cd81167
5 changed files with 47 additions and 55 deletions
@@ -82,8 +82,8 @@ import java.util.concurrent.Executors;
public class TrackRecordingService extends Service { public class TrackRecordingService extends Service {
private static final String TAG = TrackRecordingService.class.getSimpleName(); private static final String TAG = TrackRecordingService.class.getSimpleName();
public static final int PAUSE_LATITUDE = 100; public static final double PAUSE_LATITUDE = 100.0;
private static final int RESUME_LATITUDE = 200; private static final double RESUME_LATITUDE = 200.0;
// One second in milliseconds // One second in milliseconds
private static final long ONE_SECOND = 1000; private static final long ONE_SECOND = 1000;
@@ -452,9 +452,8 @@ public class TrackRecordingService extends Service {
int type = isStatistics ? Waypoint.TYPE_STATISTICS : Waypoint.TYPE_WAYPOINT; int type = isStatistics ? Waypoint.TYPE_STATISTICS : Waypoint.TYPE_WAYPOINT;
long duration; long duration;
double length; double length;
Location lastTrackPoint = myTracksProviderUtils.getLastTrackPoint(recordingTrackId); Location location = getLastValidTrackPointInCurrentSegment(recordingTrackId);
if (currentSegmentHasLocation && LocationUtils.isValidLocation(lastTrackPoint) if (location != null && trackTripStatisticsUpdater != null) {
&& trackTripStatisticsUpdater != null) {
TripStatistics stats = trackTripStatisticsUpdater.getTripStatistics(); TripStatistics stats = trackTripStatisticsUpdater.getTripStatistics();
length = stats.getTotalDistance(); length = stats.getTotalDistance();
duration = stats.getTotalTime(); duration = stats.getTotalTime();
@@ -463,14 +462,14 @@ public class TrackRecordingService extends Service {
return -1L; return -1L;
} }
// For track statistics, make it an impossible location // For track statistics, make it an impossible location
lastTrackPoint = new Location(""); location = new Location("");
lastTrackPoint.setLatitude(100); location.setLatitude(100);
lastTrackPoint.setLongitude(180); location.setLongitude(180);
length = 0; length = 0;
duration = 0; duration = 0;
} }
Waypoint waypoint = new Waypoint(name, description, category, icon, recordingTrackId, type, Waypoint waypoint = new Waypoint(name, description, category, icon, recordingTrackId, type,
length, duration, -1L, -1L, lastTrackPoint, tripStatistics); length, duration, -1L, -1L, location, tripStatistics);
Uri uri = myTracksProviderUtils.insertWaypoint(waypoint); Uri uri = myTracksProviderUtils.insertWaypoint(waypoint);
return Long.parseLong(uri.getLastPathSegment()); return Long.parseLong(uri.getLastPathSegment());
} }
@@ -701,7 +700,7 @@ public class TrackRecordingService extends Service {
// Update database // Update database
Track track = myTracksProviderUtils.getTrack(trackId); Track track = myTracksProviderUtils.getTrack(trackId);
if (track != null) { if (track != null) {
insertLocation(track, lastLocation, myTracksProviderUtils.getLastTrackPoint(trackId)); insertLocation(track, lastLocation, getLastValidTrackPointInCurrentSegment(trackId));
updateRecordingTrack(track, myTracksProviderUtils.getLastTrackPointId(trackId), false); updateRecordingTrack(track, myTracksProviderUtils.getLastTrackPointId(trackId), false);
} }
@@ -709,6 +708,18 @@ public class TrackRecordingService extends Service {
stopSelf(); stopSelf();
} }
/**
* Gets the last valid track point in the current segment. Returns null if not available.
*
* @param trackId the track id
*/
private Location getLastValidTrackPointInCurrentSegment(long trackId) {
if (!currentSegmentHasLocation) {
return null;
}
return myTracksProviderUtils.getLastValidTrackPoint(trackId);
}
/** /**
* Pauses the current track. * Pauses the current track.
*/ */
@@ -725,8 +736,7 @@ public class TrackRecordingService extends Service {
// Update database // Update database
Track track = myTracksProviderUtils.getTrack(recordingTrackId); Track track = myTracksProviderUtils.getTrack(recordingTrackId);
if (track != null) { if (track != null) {
insertLocation( insertLocation(track, lastLocation, getLastValidTrackPointInCurrentSegment(track.getId()));
track, lastLocation, myTracksProviderUtils.getLastTrackPoint(track.getId()));
Location pause = new Location(LocationManager.GPS_PROVIDER); Location pause = new Location(LocationManager.GPS_PROVIDER);
pause.setLongitude(0); pause.setLongitude(0);
@@ -809,9 +819,8 @@ public class TrackRecordingService extends Service {
return; return;
} }
Location lastTrackPoint = myTracksProviderUtils.getLastTrackPoint(track.getId()); Location lastValidTrackPoint = getLastValidTrackPointInCurrentSegment(track.getId());
long idleTime = currentSegmentHasLocation && LocationUtils.isValidLocation(lastTrackPoint) ? long idleTime = lastValidTrackPoint != null ? location.getTime() - lastValidTrackPoint.getTime()
location.getTime() - lastTrackPoint.getTime()
: 0L; : 0L;
locationListenerPolicy.updateIdleTime(idleTime); locationListenerPolicy.updateIdleTime(idleTime);
if (currentRecordingInterval != locationListenerPolicy.getDesiredPollingInterval()) { if (currentRecordingInterval != locationListenerPolicy.getDesiredPollingInterval()) {
@@ -825,41 +834,41 @@ public class TrackRecordingService extends Service {
// Always insert the first segment location // Always insert the first segment location
if (!currentSegmentHasLocation) { if (!currentSegmentHasLocation) {
insertLocation(track, location, lastTrackPoint); insertLocation(track, location, null);
currentSegmentHasLocation = true; currentSegmentHasLocation = true;
lastLocation = location; lastLocation = location;
return; return;
} }
if (!LocationUtils.isValidLocation(lastTrackPoint)) { if (!LocationUtils.isValidLocation(lastValidTrackPoint)) {
/* /*
* Should not happen. The current segment should have a location. Just * Should not happen. The current segment should have a location. Just
* insert the current location. * insert the current location.
*/ */
insertLocation(track, location, lastTrackPoint); insertLocation(track, location, null);
lastLocation = location; lastLocation = location;
return; return;
} }
double distanceToLastTrackLocation = location.distanceTo(lastTrackPoint); double distanceToLastTrackLocation = location.distanceTo(lastValidTrackPoint);
if (distanceToLastTrackLocation < minRecordingDistance && sensorDataSet == null) { if (distanceToLastTrackLocation < minRecordingDistance && sensorDataSet == null) {
Log.d(TAG, "Not recording location due to min recording distance."); Log.d(TAG, "Not recording location due to min recording distance.");
} else if (distanceToLastTrackLocation > maxRecordingDistance) { } else if (distanceToLastTrackLocation > maxRecordingDistance) {
insertLocation(track, lastLocation, lastTrackPoint); insertLocation(track, lastLocation, lastValidTrackPoint);
Location pause = new Location(LocationManager.GPS_PROVIDER); Location pause = new Location(LocationManager.GPS_PROVIDER);
pause.setLongitude(0); pause.setLongitude(0);
pause.setLatitude(PAUSE_LATITUDE); pause.setLatitude(PAUSE_LATITUDE);
pause.setTime(lastLocation.getTime()); pause.setTime(lastLocation.getTime());
insertLocation(track, pause, null); insertLocation(track, pause, null);
insertLocation(track, location, lastTrackPoint); insertLocation(track, location, null);
} else { } else {
/* /*
* (distanceToLastTrackLocation >= minRecordingDistance || * (distanceToLastTrackLocation >= minRecordingDistance ||
* hasSensorData) && distanceToLastTrackLocation <= maxRecordingDistance * hasSensorData) && distanceToLastTrackLocation <= maxRecordingDistance
*/ */
insertLocation(track, lastLocation, lastTrackPoint); insertLocation(track, lastLocation, lastValidTrackPoint);
insertLocation(track, location, lastTrackPoint); insertLocation(track, location, null);
} }
lastLocation = location; lastLocation = location;
} catch (Error e) { } catch (Error e) {
@@ -871,13 +880,21 @@ public class TrackRecordingService extends Service {
} }
} }
private void insertLocation(Track track, Location location, Location lastRecordedLocation) { /**
* Inserts a location.
*
* @param track the track
* @param location the location
* @param lastValidTrackPoint the last valid track point, can be null
*/
private void insertLocation(Track track, Location location, Location lastValidTrackPoint) {
if (location == null) { if (location == null) {
Log.w(TAG, "Ignore insertLocation. loation is null."); Log.w(TAG, "Ignore insertLocation. loation is null.");
return; return;
} }
if (location.equals(lastRecordedLocation)) { // Do not insert if inserted already
Log.w(TAG, "Ignore insertLocation. loation same as last recorded location."); if (lastValidTrackPoint != null && lastValidTrackPoint.getTime() == location.getTime()) {
Log.w(TAG, "Ignore insertLocation. location time same as last valid track point time.");
return; return;
} }
@@ -96,6 +96,10 @@ public class TripStatisticsUpdater {
if (!LocationUtils.isValidLocation(location)) { if (!LocationUtils.isValidLocation(location)) {
updateTime(location.getTime()); updateTime(location.getTime());
if (location.getLatitude() == TrackRecordingService.PAUSE_LATITUDE) { if (location.getLatitude() == TrackRecordingService.PAUSE_LATITUDE) {
if (lastLocation != null && lastMovingLocation != null
&& lastLocation != lastMovingLocation) {
currentSegment.addTotalDistance(lastMovingLocation.distanceTo(lastLocation));
}
tripStatistics.merge(currentSegment); tripStatistics.merge(currentSegment);
} }
currentSegment = init(location.getTime()); currentSegment = init(location.getTime());
@@ -211,13 +211,6 @@ public interface MyTracksProviderUtils {
*/ */
public Location createTrackPoint(Cursor cursor); public Location createTrackPoint(Cursor cursor);
/**
* Gets the last location for a track. Returns null if it doesn't exist.
*
* @param trackId the track id
*/
public Location getLastTrackPoint(long trackId);
/** /**
* Gets the last location id for a track. Returns -1L if it doesn't exist. * Gets the last location id for a track. Returns -1L if it doesn't exist.
* *
@@ -697,17 +697,6 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
return location; return location;
} }
@Override
public Location getLastTrackPoint(long trackId) {
if (trackId < 0) {
return null;
}
String selection = TrackPointsColumns._ID + "=(select max(" + TrackPointsColumns._ID + ") from "
+ TrackPointsColumns.TABLE_NAME + " WHERE " + TrackPointsColumns.TRACKID + "=?)";
String[] selectionArgs = new String[] { Long.toString(trackId) };
return findTrackPointBy(selection, selectionArgs);
}
@Override @Override
public long getLastTrackPointId(long trackId) { public long getLastTrackPointId(long trackId) {
if (trackId < 0) { if (trackId < 0) {
@@ -746,17 +746,6 @@ public class MyTracksProviderUtilsImplTest extends AndroidTestCase {
assertEquals(11, providerUtils.getTrackPointCursor(trackId, 0, 1000, false).getCount()); assertEquals(11, providerUtils.getTrackPointCursor(trackId, 0, 1000, false).getCount());
} }
/**
* Tests the method {@link MyTracksProviderUtilsImpl#getLastTrackPoint(long)}.
*/
public void testGetLastTrackPoint() {
// Insert track, point at first.
long trackId = System.currentTimeMillis();
Track track = getTrack(trackId, 10);
insertTrackWithLocations(track);
checkLocation(9, providerUtils.getLastTrackPoint(trackId));
}
/** /**
* Tests the method {@link MyTracksProviderUtilsImpl#getLastTrackPointId(long)}. * Tests the method {@link MyTracksProviderUtilsImpl#getLastTrackPointId(long)}.
*/ */