diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/provider/CustomContentProviderUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/content/provider/CustomContentProviderUtilsTest.java index 7577f70ba..026d85eba 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/content/provider/CustomContentProviderUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/content/provider/CustomContentProviderUtilsTest.java @@ -87,50 +87,37 @@ public class CustomContentProviderUtilsTest { @Test public void testLocationIterator_noPoints() { - testIterator(new Track.Id(1), 0, 1, false); + testIterator(new Track.Id(1), 0, 1); } @Test public void testLocationIterator_noBatchAscending() { - testIterator(new Track.Id(1), 50, 100, false); - testIterator(new Track.Id(2), 50, 50, false); - } - - @Test - public void testLocationIterator_noBatchDescending() { - testIterator(new Track.Id(1), 50, 100, true); - testIterator(new Track.Id(2), 50, 50, true); + testIterator(new Track.Id(1), 50, 100); + testIterator(new Track.Id(2), 50, 50); } @Test public void testLocationIterator_batchAscending() { - testIterator(new Track.Id(1), 50, 11, false); - testIterator(new Track.Id(2), 50, 25, false); - } - - @Test - public void testLocationIterator_batchDescending() { - testIterator(new Track.Id(1), 50, 11, true); - testIterator(new Track.Id(2), 50, 25, true); + testIterator(new Track.Id(1), 50, 11); + testIterator(new Track.Id(2), 50, 25); } @Test public void testLocationIterator_largeTrack() { - testIterator(new Track.Id(1), 20000, 2000, false); + testIterator(new Track.Id(1), 20000, 2000); } - private void testIterator(Track.Id trackId, int numPoints, int batchSize, boolean descending) { + private void testIterator(Track.Id trackId, int numPoints, int batchSize) { long lastPointId = initializeTrack(trackId, numPoints); contentProviderUtils.setDefaultCursorBatchSize(batchSize); List locations = new ArrayList<>(numPoints); - try (TrackPointIterator it = contentProviderUtils.getTrackPointLocationIterator(trackId, -1L, descending)) { + try (TrackPointIterator it = contentProviderUtils.getTrackPointLocationIterator(trackId, -1L)) { while (it.hasNext()) { TrackPoint loc = it.next(); assertNotNull(loc); locations.add(loc); // Make sure the IDs are returned in the right order. - assertEquals(descending ? lastPointId - locations.size() + 1 - : lastPointId - numPoints + locations.size(), it.getTrackPointId()); + assertEquals(lastPointId - numPoints + locations.size(), it.getTrackPointId()); } assertEquals(numPoints, locations.size()); } @@ -158,7 +145,7 @@ public class CustomContentProviderUtilsTest { // Load all inserted trackPoints. long lastPointId = -1; int counter = 0; - try (TrackPointIterator it = contentProviderUtils.getTrackPointLocationIterator(id, -1L, false)) { + try (TrackPointIterator it = contentProviderUtils.getTrackPointLocationIterator(id, -1L)) { while (it.hasNext()) { it.next(); lastPointId = it.getTrackPointId(); @@ -778,9 +765,9 @@ public class CustomContentProviderUtilsTest { // when / then contentProviderUtils.bulkInsertTrackPoint(track.second, trackId); - assertEquals(20, contentProviderUtils.getTrackPointCursor(trackId, -1L, 1000, false).getCount()); + assertEquals(20, contentProviderUtils.getTrackPointCursor(trackId, -1L, 1000).getCount()); contentProviderUtils.bulkInsertTrackPoint(Arrays.copyOfRange(track.second, 0, 8), trackId); - assertEquals(28, contentProviderUtils.getTrackPointCursor(trackId, -1L, 1000, false).getCount()); + assertEquals(28, contentProviderUtils.getTrackPointCursor(trackId, -1L, 1000).getCount()); } /** @@ -875,31 +862,6 @@ public class CustomContentProviderUtilsTest { checkLocation(9, lastTrackPoint.getLocation()); } - /** - * Tests the method {@link ContentProviderUtils#getTrackPointCursor(Track.Id, long, int, boolean)} in descending. - */ - @Test - public void testGetTrackPointCursor_desc() { - // given - Track.Id trackId = new Track.Id(System.currentTimeMillis()); - Pair track = TestDataUtil.createTrack(trackId, 10); - contentProviderUtils.insertTrack(track.first); - - long[] trackpointIds = new long[track.second.length]; - for (int i = 0; i < trackpointIds.length; i++) { - trackpointIds[i] = ContentUris.parseId(contentProviderUtils.insertTrackPoint(track.second[i], track.first.getId())); - } - - // when - Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackpointIds[1], 5, true); - - // then - assertEquals(2, cursor.getCount()); - } - - /** - * Tests the method {@link ContentProviderUtils#getTrackPointCursor(Track.Id, long, int, boolean)} in ascending. - */ @Test public void testGetTrackPointCursor_asc() { // given @@ -913,44 +875,12 @@ public class CustomContentProviderUtilsTest { } // when - Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackpointIds[8], 5, false); + Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackpointIds[8], 5); // then assertEquals(2, cursor.getCount()); } - /** - * Tests the method {@link ContentProviderUtils#getTrackPointLocationIterator(Track.Id, long, boolean)} in descending. - */ - @Test - public void testGetTrackPointLocationIterator_desc() { - // given - Track.Id trackId = new Track.Id(System.currentTimeMillis()); - Pair track = TestDataUtil.createTrack(trackId, 10); - contentProviderUtils.insertTrack(track.first); - - long[] trackpointIds = new long[track.second.length]; - for (int i = 0; i < trackpointIds.length; i++) { - trackpointIds[i] = ContentUris.parseId(contentProviderUtils.insertTrackPoint(track.second[i], track.first.getId())); - } - - long startTrackPointId = trackpointIds[9]; - // when - TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, startTrackPointId, true); - - // then - for (int i = 0; i < trackpointIds.length; i++) { - assertTrue(trackPointIterator.hasNext()); - TrackPoint trackPoint = trackPointIterator.next(); - assertEquals(startTrackPointId - i, trackPointIterator.getTrackPointId()); - checkLocation((trackpointIds.length - 1) - i, trackPoint.getLocation()); - } - assertFalse(trackPointIterator.hasNext()); - } - - /** - * Tests the method {@link ContentProviderUtils#getTrackPointLocationIterator(Track.Id, long, boolean)} in ascending. - */ @Test public void testGetTrackPointLocationIterator_asc() { // given @@ -966,7 +896,7 @@ public class CustomContentProviderUtilsTest { long startTrackPointId = trackpointIds[0]; // when - TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, startTrackPointId, false); + TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, startTrackPointId); // then for (int i = 0; i < trackpointIds.length; i++) { diff --git a/src/main/java/de/dennisguse/opentracks/content/TrackDataHub.java b/src/main/java/de/dennisguse/opentracks/content/TrackDataHub.java index 28758833d..e2eb9ff4a 100644 --- a/src/main/java/de/dennisguse/opentracks/content/TrackDataHub.java +++ b/src/main/java/de/dennisguse/opentracks/content/TrackDataHub.java @@ -364,7 +364,7 @@ public class TrackDataHub implements SharedPreferences.OnSharedPreferenceChangeL int samplingFrequency = -1; boolean includeNextPoint = false; - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(selectedTrackId, localLastSeenTrackPointIdId + 1, false)) { + try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(selectedTrackId, localLastSeenTrackPointIdId + 1)) { while (trackPointIterator.hasNext()) { TrackPoint trackPoint = trackPointIterator.next(); diff --git a/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java b/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java index d33bc9103..7993073ff 100644 --- a/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java +++ b/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java @@ -680,27 +680,22 @@ public class ContentProviderUtils { * Creates a location cursor. The caller owns the returned cursor and is responsible for closing it. * * @param trackId the track id - * @param startTrackPointId the starting trackPoint id. -1L to ignore - * @param maxLocations maximum number of locations to return. -1 for no limit - * @param descending true to sort the result in descending order (latest location first) + * @param startTrackPointId the starting trackPoint id. `null` to ignore + * @param maxLocations maximum number of locations to return. `null` for no limit */ - public Cursor getTrackPointCursor(Track.Id trackId, long startTrackPointId, int maxLocations, boolean descending) { + public Cursor getTrackPointCursor(Track.Id trackId, Long startTrackPointId, Integer maxLocations) { String selection; String[] selectionArgs; - if (startTrackPointId >= 0) { - String comparison = descending ? "<=" : ">="; - selection = TrackPointsColumns.TRACKID + "=? AND " + TrackPointsColumns._ID + comparison + "?"; + if (startTrackPointId != null) { + selection = TrackPointsColumns.TRACKID + "=? AND " + TrackPointsColumns._ID + ">=?"; selectionArgs = new String[]{Long.toString(trackId.getId()), Long.toString(startTrackPointId)}; } else { selection = TrackPointsColumns.TRACKID + "=?"; selectionArgs = new String[]{Long.toString(trackId.getId())}; } - String sortOrder = TrackPointsColumns._ID; - if (descending) { - sortOrder += " DESC"; - } - if (maxLocations >= 0) { + String sortOrder = TrackPointsColumns.DEFAULT_SORT_ORDER; + if (maxLocations != null) { sortOrder += " LIMIT " + maxLocations; } return getTrackPointCursor(null, selection, selectionArgs, sortOrder); @@ -784,11 +779,10 @@ public class ContentProviderUtils { * When done with iteration, {@link TrackPointIterator#close()} must be called. * * @param trackId the track id - * @param startTrackPointId the starting trackPoint id. -1L to ignore - * @param descending true to sort the result in descending order (latest location first) + * @param startTrackPointId the starting trackPoint id. `null` to ignore */ - public TrackPointIterator getTrackPointLocationIterator(final Track.Id trackId, final long startTrackPointId, final boolean descending) { - return new TrackPointIterator(this, trackId, startTrackPointId, descending); + public TrackPointIterator getTrackPointLocationIterator(final Track.Id trackId, final Long startTrackPointId) { + return new TrackPointIterator(this, trackId, startTrackPointId); } private TrackPoint findTrackPointBy(String selection, String[] selectionArgs) { @@ -816,7 +810,7 @@ public class ContentProviderUtils { public List getTrackPoints(Track.Id trackId) { List trackPoints = null; - try (Cursor trackPointCursor = getTrackPointCursor(trackId, -1L, -1, false)) { + try (Cursor trackPointCursor = getTrackPointCursor(trackId, -1L, -1)) { if (trackPointCursor != null) { trackPointCursor.moveToFirst(); trackPoints = new ArrayList<>(trackPointCursor.getCount()); diff --git a/src/main/java/de/dennisguse/opentracks/content/provider/TrackPointIterator.java b/src/main/java/de/dennisguse/opentracks/content/provider/TrackPointIterator.java index de6735c05..cef7b89c0 100644 --- a/src/main/java/de/dennisguse/opentracks/content/provider/TrackPointIterator.java +++ b/src/main/java/de/dennisguse/opentracks/content/provider/TrackPointIterator.java @@ -18,16 +18,14 @@ public class TrackPointIterator implements Iterator, AutoCloseable { private final ContentProviderUtils contentProviderUtils; private final Track.Id trackId; - private final boolean descending; private final CachedTrackPointsIndexes indexes; private long lastTrackPointId = -1L; private Cursor cursor; - public TrackPointIterator(ContentProviderUtils contentProviderUtils, Track.Id trackId, long startTrackPointId, boolean descending) { + public TrackPointIterator(ContentProviderUtils contentProviderUtils, Track.Id trackId, Long startTrackPointId) { this.contentProviderUtils = contentProviderUtils; this.trackId = trackId; - this.descending = descending; cursor = getCursor(startTrackPointId); indexes = cursor != null ? new CachedTrackPointsIndexes(cursor) @@ -40,14 +38,14 @@ public class TrackPointIterator implements Iterator, AutoCloseable { * @param trackPointId the starting track point id */ private Cursor getCursor(long trackPointId) { - return contentProviderUtils.getTrackPointCursor(trackId, trackPointId, contentProviderUtils.getDefaultCursorBatchSize(), descending); + return contentProviderUtils.getTrackPointCursor(trackId, trackPointId, contentProviderUtils.getDefaultCursorBatchSize()); } /** * Advances the cursor to the next batch. Returns true if successful. */ private boolean advanceCursorToNextBatch() { - long trackPointId = lastTrackPointId == -1L ? -1L : lastTrackPointId + (descending ? -1 : 1); + long trackPointId = lastTrackPointId == -1L ? -1L : lastTrackPointId + 1; Log.d(TAG, "Advancing track point id: " + trackPointId); cursor.close(); cursor = getCursor(trackPointId); diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/FileTrackExporter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/FileTrackExporter.java index 595527156..8d38b2b7d 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/FileTrackExporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/FileTrackExporter.java @@ -126,7 +126,7 @@ public class FileTrackExporter implements TrackExporter { boolean isLastLocationValid = false; TrackPoint lastTrackPoint = null; - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L, false)) { + try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L)) { while (trackPointIterator.hasNext()) { if (Thread.interrupted()) { diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/KmlTrackWriter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/KmlTrackWriter.java index 3a2c21309..ac8ac4d0f 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/KmlTrackWriter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/KmlTrackWriter.java @@ -16,7 +16,6 @@ package de.dennisguse.opentracks.io.file.exporter; import android.content.Context; -import android.database.Cursor; import android.location.Location; import java.io.OutputStream; @@ -403,15 +402,12 @@ public class KmlTrackWriter implements TrackWriter { if (trackPointId == -1L) { return location.getBearing(); } - TrackPoint viewLocation; - try (Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackPointId, 10, true)) { - if (cursor == null || cursor.getCount() == 0) { - return location.getBearing(); - } - cursor.moveToPosition(cursor.getCount() - 1); - viewLocation = contentProviderUtils.createTrackPoint(cursor); + TrackPoint viewLocation = contentProviderUtils.getLastValidTrackPoint(trackId); + if (viewLocation != null) { + return viewLocation.bearingTo(location); } - return viewLocation.bearingTo(location); + + return location.getBearing(); } private String getCoordinates(Location location, String separator) { diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/AbstractFileTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/AbstractFileTrackImporter.java index 033374845..e330c27a6 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/AbstractFileTrackImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/AbstractFileTrackImporter.java @@ -160,7 +160,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track // TODO Should not be necessary anymore? TrackStatisticsUpdater markerTrackStatisticsUpdater = new TrackStatisticsUpdater(track.getTrackStatistics().getStartTime_ms()); - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L, false)) { + try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L)) { while (true) { if (marker == null) { diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java index 14f14c35c..6e9581add 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java @@ -352,7 +352,7 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand trackStatisticsUpdater = new TrackStatisticsUpdater(track.getTrackStatistics().getStartTime_ms()); - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L, false)) { + try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L)) { trackStatisticsUpdater.addTrackPoint(trackPointIterator, recordingDistanceInterval); } catch (RuntimeException e) { Log.e(TAG, "RuntimeException", e);