Allow importer to update an existing track. Add clearTrack in MyTracksProviderUtils

This commit is contained in:
Jimmy Shih
2013-01-23 11:04:15 -08:00
parent 6b5f9c976b
commit 07cd1dcdbb
6 changed files with 95 additions and 32 deletions
@@ -101,6 +101,7 @@ abstract class AbstractImporter extends DefaultHandler {
private static final int MAX_BUFFERED_LOCATIONS = 512;
private final Context context;
private final long importTrackId;
private final MyTracksProviderUtils myTracksProviderUtils;
private final int minRecordingDistance;
private final List<Long> trackIds;
@@ -124,17 +125,25 @@ abstract class AbstractImporter extends DefaultHandler {
protected String time;
protected String waypointType;
protected AbstractImporter(Context context) {
this(context, MyTracksProviderUtils.Factory.get(context));
/**
* Constructor.
*
* @param context the context
* @param importTrackId the track id to import to. -1L to import to a new
* track.
*/
protected AbstractImporter(Context context, long importTrackId) {
this(context, importTrackId, MyTracksProviderUtils.Factory.get(context));
}
@VisibleForTesting
protected AbstractImporter(
Context context, MyTracksProviderUtils myTracksProviderUtils) {
Context context, long importTrackId, MyTracksProviderUtils myTracksProviderUtils) {
this.context = context;
this.importTrackId = importTrackId;
this.myTracksProviderUtils = myTracksProviderUtils;
this.minRecordingDistance = PreferencesUtils.getInt(context, R.string.min_recording_distance_key,
PreferencesUtils.MIN_RECORDING_DISTANCE_DEFAULT);
this.minRecordingDistance = PreferencesUtils.getInt(context,
R.string.min_recording_distance_key, PreferencesUtils.MIN_RECORDING_DISTANCE_DEFAULT);
trackIds = new ArrayList<Long>();
waypoints = new ArrayList<Waypoint>();
}
@@ -286,12 +295,22 @@ abstract class AbstractImporter extends DefaultHandler {
/**
* On track start.
*/
protected void onTrackStart() {
protected void onTrackStart() throws SAXException {
trackData = new TrackData();
Uri uri = myTracksProviderUtils.insertTrack(trackData.track);
long id = Long.parseLong(uri.getLastPathSegment());
trackIds.add(id);
trackData.track.setId(id);
long trackId;
if (importTrackId == -1L) {
Uri uri = myTracksProviderUtils.insertTrack(trackData.track);
trackId = Long.parseLong(uri.getLastPathSegment());
} else {
if (trackIds.size() > 0) {
throw new SAXException(createErrorMessage(
"Cannot import more than one track to an existing track " + importTrackId));
}
trackId = importTrackId;
myTracksProviderUtils.clearTrack(trackId);
}
trackIds.add(trackId);
trackData.track.setId(trackId);
}
/**
@@ -48,13 +48,19 @@ public class GpxImporter extends AbstractImporter {
private static final String ATTRIBUTE_LAT = "lat";
private static final String ATTRIBUTE_LON = "lon";
public GpxImporter(Context context) {
super(context);
/**
* Constructor.
*
* @param context the context
* @param importTrackId track id to import to. -1L to import to a new track.
*/
public GpxImporter(Context context, long importTrackId) {
super(context, importTrackId);
}
@VisibleForTesting
public GpxImporter(Context context, MyTracksProviderUtils myTracksProviderUtils) {
super(context, myTracksProviderUtils);
super(context, -1L, myTracksProviderUtils);
}
@Override
@@ -112,7 +118,7 @@ public class GpxImporter extends AbstractImporter {
}
@Override
protected void onTrackStart() {
protected void onTrackStart() throws SAXException {
super.onTrackStart();
name = null;
description = null;
@@ -73,7 +73,7 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
this.trackFileFormat = trackFileFormat;
this.path = path;
context = importActivity.getApplicationContext();
// Get the wake lock if not recording or paused
if (PreferencesUtils.getLong(importActivity, R.string.recording_track_id_key)
== PreferencesUtils.RECORDING_TRACK_ID_DEFAULT || PreferencesUtils.getBoolean(
@@ -157,8 +157,9 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
*/
private boolean importFile(final File file) {
try {
AbstractImporter importer = trackFileFormat == TrackFileFormat.KML ? new KmlImporter(context)
: new GpxImporter(context);
AbstractImporter importer = trackFileFormat == TrackFileFormat.KML ? new KmlImporter(
context, -1L)
: new GpxImporter(context, -1L);
long trackIds[] = importer.importFile(new FileInputStream(file));
int length = trackIds.length;
if (length > 0) {
@@ -67,15 +67,21 @@ public class KmlImporter extends AbstractImporter {
private ArrayList<Integer> heartRateList;
private ArrayList<Integer> powerList;
public KmlImporter(Context context) {
super(context);
/**
* Constructor.
*
* @param context the context
* @param importTrackId track id to import to. -1L to import to a new track.
*/
public KmlImporter(Context context, long importTrackId) {
super(context, importTrackId);
}
@VisibleForTesting
public KmlImporter(Context context, MyTracksProviderUtils myTracksProviderUtils) {
super(context, myTracksProviderUtils);
super(context, -1L, myTracksProviderUtils);
}
@Override
public void startElement(String uri, String localName, String tag, Attributes attributes)
throws SAXException {
@@ -40,6 +40,13 @@ public interface MyTracksProviderUtils {
*/
public static final String AUTHORITY = "com.google.android.maps.mytracks";
/**
* Clears a track. Removes waypoints and trackpoints. Only keeps the track id.
*
* @param trackId the track id
*/
public void clearTrack(long trackId);
/**
* Creates a {@link Track} from a cursor.
*
@@ -122,7 +129,8 @@ public interface MyTracksProviderUtils {
* deletion. The generator is used to update the next statistics waypoint.
*
* @param waypointId the waypoint id
* @param descriptionGenerator the description generator. Can be null for waypoint marker
* @param descriptionGenerator the description generator. Can be null for
* waypoint marker
*/
public void deleteWaypoint(long waypointId, DescriptionGenerator descriptionGenerator);
@@ -143,8 +151,8 @@ public interface MyTracksProviderUtils {
public Waypoint getLastWaypoint(long trackId, WaypointType waypointType);
/**
* Gets the next waypoint number for a type. Returns -1 if not able to get the next
* waypoint number.
* Gets the next waypoint number for a type. Returns -1 if not able to get the
* next waypoint number.
*
* @param trackId the track id
* @param waypointType the waypoint type
@@ -165,7 +173,8 @@ public interface MyTracksProviderUtils {
* @param selection the selection. Can be null
* @param selectionArgs the selection arguments. Can be null
* @param sortOrder the sort order. Can be null
* @param maxWaypoints the maximum number of waypoints to return. -1 for no limit
* @param maxWaypoints the maximum number of waypoints to return. -1 for no
* limit
*/
public Cursor getWaypointCursor(
String selection, String[] selectionArgs, String sortOrder, int maxWaypoints);
@@ -176,7 +185,8 @@ public interface MyTracksProviderUtils {
*
* @param trackId the track id
* @param minWaypointId the minimum waypoint id. -1L to ignore
* @param maxWaypoints the maximum number of waypoints to return. -1 for no limit
* @param maxWaypoints the maximum number of waypoints to return. -1 for no
* limit
*/
public Cursor getWaypointCursor(long trackId, long minWaypointId, int maxWaypoints);
@@ -228,12 +238,13 @@ public interface MyTracksProviderUtils {
public long getLastTrackPointId(long trackId);
/**
* Gets the first valid location for a track. Returns null if it doesn't exist.
* Gets the first valid location for a track. Returns null if it doesn't
* exist.
*
* @param trackId the track id
*/
public Location getFirstValidTrackPoint(long trackId);
/**
* Gets the last valid location for a track. Returns null if it doesn't exist.
*
@@ -50,6 +50,14 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
this.contentResolver = contentResolver;
}
@Override
public void clearTrack(long trackId) {
deleteTrackPointsAndWaypoints(trackId);
Track track = new Track();
track.setId(trackId);
updateTrack(track);
}
@Override
public Track createTrack(Cursor cursor) {
int idIndex = cursor.getColumnIndexOrThrow(TracksColumns._ID);
@@ -164,6 +172,21 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
@Override
public void deleteTrack(long trackId) {
deleteTrackPointsAndWaypoints(trackId);
// Delete track last since it triggers a database vaccum call
contentResolver.delete(TracksColumns.CONTENT_URI, TracksColumns._ID + "=?",
new String[] { Long.toString(trackId) });
}
/**
* Deletes track points and waypoints of a track. Assumes
* {@link TracksColumns#STARTID}, {@link TracksColumns#STOPID}, and
* {@link TracksColumns#NUMPOINTS} will be updated by the caller.
*
* @param trackId the track id
*/
private void deleteTrackPointsAndWaypoints(long trackId) {
Track track = getTrack(trackId);
if (track != null) {
String where = TrackPointsColumns._ID + ">=? AND " + TrackPointsColumns._ID + "<=?";
@@ -173,9 +196,6 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
}
contentResolver.delete(WaypointsColumns.CONTENT_URI, WaypointsColumns.TRACKID + "=?",
new String[] { Long.toString(trackId) });
// Delete tracks last since it triggers a database vaccum call
contentResolver.delete(TracksColumns.CONTENT_URI, TracksColumns._ID + "=?",
new String[] { Long.toString(trackId) });
}
@Override
@@ -759,7 +779,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
String[] selectionArgs = new String[] { Long.toString(trackId) };
return findTrackPointBy(selection, selectionArgs);
}
@Override
public Location getLastValidTrackPoint(long trackId) {
if (trackId < 0) {