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 static final int MAX_BUFFERED_LOCATIONS = 512;
private final Context context; private final Context context;
private final long importTrackId;
private final MyTracksProviderUtils myTracksProviderUtils; private final MyTracksProviderUtils myTracksProviderUtils;
private final int minRecordingDistance; private final int minRecordingDistance;
private final List<Long> trackIds; private final List<Long> trackIds;
@@ -124,17 +125,25 @@ abstract class AbstractImporter extends DefaultHandler {
protected String time; protected String time;
protected String waypointType; 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 @VisibleForTesting
protected AbstractImporter( protected AbstractImporter(
Context context, MyTracksProviderUtils myTracksProviderUtils) { Context context, long importTrackId, MyTracksProviderUtils myTracksProviderUtils) {
this.context = context; this.context = context;
this.importTrackId = importTrackId;
this.myTracksProviderUtils = myTracksProviderUtils; this.myTracksProviderUtils = myTracksProviderUtils;
this.minRecordingDistance = PreferencesUtils.getInt(context, R.string.min_recording_distance_key, this.minRecordingDistance = PreferencesUtils.getInt(context,
PreferencesUtils.MIN_RECORDING_DISTANCE_DEFAULT); R.string.min_recording_distance_key, PreferencesUtils.MIN_RECORDING_DISTANCE_DEFAULT);
trackIds = new ArrayList<Long>(); trackIds = new ArrayList<Long>();
waypoints = new ArrayList<Waypoint>(); waypoints = new ArrayList<Waypoint>();
} }
@@ -286,12 +295,22 @@ abstract class AbstractImporter extends DefaultHandler {
/** /**
* On track start. * On track start.
*/ */
protected void onTrackStart() { protected void onTrackStart() throws SAXException {
trackData = new TrackData(); trackData = new TrackData();
Uri uri = myTracksProviderUtils.insertTrack(trackData.track); long trackId;
long id = Long.parseLong(uri.getLastPathSegment()); if (importTrackId == -1L) {
trackIds.add(id); Uri uri = myTracksProviderUtils.insertTrack(trackData.track);
trackData.track.setId(id); 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_LAT = "lat";
private static final String ATTRIBUTE_LON = "lon"; 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 @VisibleForTesting
public GpxImporter(Context context, MyTracksProviderUtils myTracksProviderUtils) { public GpxImporter(Context context, MyTracksProviderUtils myTracksProviderUtils) {
super(context, myTracksProviderUtils); super(context, -1L, myTracksProviderUtils);
} }
@Override @Override
@@ -112,7 +118,7 @@ public class GpxImporter extends AbstractImporter {
} }
@Override @Override
protected void onTrackStart() { protected void onTrackStart() throws SAXException {
super.onTrackStart(); super.onTrackStart();
name = null; name = null;
description = null; description = null;
@@ -157,8 +157,9 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
*/ */
private boolean importFile(final File file) { private boolean importFile(final File file) {
try { try {
AbstractImporter importer = trackFileFormat == TrackFileFormat.KML ? new KmlImporter(context) AbstractImporter importer = trackFileFormat == TrackFileFormat.KML ? new KmlImporter(
: new GpxImporter(context); context, -1L)
: new GpxImporter(context, -1L);
long trackIds[] = importer.importFile(new FileInputStream(file)); long trackIds[] = importer.importFile(new FileInputStream(file));
int length = trackIds.length; int length = trackIds.length;
if (length > 0) { if (length > 0) {
@@ -67,13 +67,19 @@ public class KmlImporter extends AbstractImporter {
private ArrayList<Integer> heartRateList; private ArrayList<Integer> heartRateList;
private ArrayList<Integer> powerList; 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 @VisibleForTesting
public KmlImporter(Context context, MyTracksProviderUtils myTracksProviderUtils) { public KmlImporter(Context context, MyTracksProviderUtils myTracksProviderUtils) {
super(context, myTracksProviderUtils); super(context, -1L, myTracksProviderUtils);
} }
@Override @Override
@@ -40,6 +40,13 @@ public interface MyTracksProviderUtils {
*/ */
public static final String AUTHORITY = "com.google.android.maps.mytracks"; 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. * 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. * deletion. The generator is used to update the next statistics waypoint.
* *
* @param waypointId the waypoint id * @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); public void deleteWaypoint(long waypointId, DescriptionGenerator descriptionGenerator);
@@ -143,8 +151,8 @@ public interface MyTracksProviderUtils {
public Waypoint getLastWaypoint(long trackId, WaypointType waypointType); public Waypoint getLastWaypoint(long trackId, WaypointType waypointType);
/** /**
* Gets the next waypoint number for a type. Returns -1 if not able to get the next * Gets the next waypoint number for a type. Returns -1 if not able to get the
* waypoint number. * next waypoint number.
* *
* @param trackId the track id * @param trackId the track id
* @param waypointType the waypoint type * @param waypointType the waypoint type
@@ -165,7 +173,8 @@ public interface MyTracksProviderUtils {
* @param selection the selection. Can be null * @param selection the selection. Can be null
* @param selectionArgs the selection arguments. Can be null * @param selectionArgs the selection arguments. Can be null
* @param sortOrder the sort order. 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( public Cursor getWaypointCursor(
String selection, String[] selectionArgs, String sortOrder, int maxWaypoints); String selection, String[] selectionArgs, String sortOrder, int maxWaypoints);
@@ -176,7 +185,8 @@ public interface MyTracksProviderUtils {
* *
* @param trackId the track id * @param trackId the track id
* @param minWaypointId the minimum waypoint id. -1L to ignore * @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); public Cursor getWaypointCursor(long trackId, long minWaypointId, int maxWaypoints);
@@ -228,7 +238,8 @@ public interface MyTracksProviderUtils {
public long getLastTrackPointId(long trackId); 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 * @param trackId the track id
*/ */
@@ -50,6 +50,14 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
this.contentResolver = contentResolver; this.contentResolver = contentResolver;
} }
@Override
public void clearTrack(long trackId) {
deleteTrackPointsAndWaypoints(trackId);
Track track = new Track();
track.setId(trackId);
updateTrack(track);
}
@Override @Override
public Track createTrack(Cursor cursor) { public Track createTrack(Cursor cursor) {
int idIndex = cursor.getColumnIndexOrThrow(TracksColumns._ID); int idIndex = cursor.getColumnIndexOrThrow(TracksColumns._ID);
@@ -164,6 +172,21 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
@Override @Override
public void deleteTrack(long trackId) { 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); Track track = getTrack(trackId);
if (track != null) { if (track != null) {
String where = TrackPointsColumns._ID + ">=? AND " + TrackPointsColumns._ID + "<=?"; String where = TrackPointsColumns._ID + ">=? AND " + TrackPointsColumns._ID + "<=?";
@@ -173,9 +196,6 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
} }
contentResolver.delete(WaypointsColumns.CONTENT_URI, WaypointsColumns.TRACKID + "=?", contentResolver.delete(WaypointsColumns.CONTENT_URI, WaypointsColumns.TRACKID + "=?",
new String[] { Long.toString(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 @Override