forked from upstream-mirrors/OpenTracks
Cleanup: AutoCloseableIterator now handles the cursor.
This commit is contained in:
@@ -13,6 +13,8 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.data.MarkerIterator;
|
||||
import de.dennisguse.opentracks.data.TrackPointIterator;
|
||||
import de.dennisguse.opentracks.data.models.ActivityType;
|
||||
import de.dennisguse.opentracks.data.models.Altitude;
|
||||
import de.dennisguse.opentracks.data.models.Distance;
|
||||
@@ -23,7 +25,6 @@ import de.dennisguse.opentracks.data.models.Statistics;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
import de.dennisguse.opentracks.ui.markers.MarkerUtils;
|
||||
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
import de.dennisguse.opentracks.util.FileUtils;
|
||||
|
||||
public class TestDataUtil {
|
||||
@@ -168,7 +169,7 @@ public class TestDataUtil {
|
||||
}
|
||||
|
||||
public static List<TrackPoint> getTrackPoints(ContentProviderUtils contentProviderUtils, Track.Id trackId) {
|
||||
try (AutoCloseableIterator<TrackPoint> trackPointIterator = contentProviderUtils.getTrackPointIterator(trackId, null)) {
|
||||
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointIterator(trackId, null)) {
|
||||
ArrayList<TrackPoint> trackPoints = new ArrayList<>();
|
||||
trackPointIterator.forEachRemaining(trackPoints::add);
|
||||
return trackPoints;
|
||||
@@ -176,7 +177,7 @@ public class TestDataUtil {
|
||||
}
|
||||
|
||||
public static List<Marker> getMarkers(ContentProviderUtils contentProviderUtils, Track.Id trackId) {
|
||||
try (AutoCloseableIterator<Marker> trackPointIterator = contentProviderUtils.getMarkerIterator(trackId)) {
|
||||
try (MarkerIterator trackPointIterator = contentProviderUtils.getMarkerIterator(trackId)) {
|
||||
ArrayList<Marker> markers = new ArrayList<>();
|
||||
trackPointIterator.forEachRemaining(markers::add);
|
||||
return markers;
|
||||
|
||||
+4
-5
@@ -67,7 +67,6 @@ import de.dennisguse.opentracks.data.tables.MarkerColumns;
|
||||
import de.dennisguse.opentracks.data.tables.TrackPointsColumns;
|
||||
import de.dennisguse.opentracks.data.tables.TracksColumns;
|
||||
import de.dennisguse.opentracks.stats.SensorStatistics;
|
||||
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
import de.dennisguse.opentracks.util.FileUtils;
|
||||
|
||||
/**
|
||||
@@ -119,7 +118,7 @@ public class CustomContentProviderUtilsTest {
|
||||
private void testIterator(Track.Id trackId, int numPoints) {
|
||||
TrackPoint.Id lastPointId = initializeTrack(trackId, numPoints);
|
||||
List<TrackPoint> locations = new ArrayList<>(numPoints);
|
||||
try (AutoCloseableIterator<TrackPoint> it = contentProviderUtils.getTrackPointIterator(trackId, null)) {
|
||||
try (TrackPointIterator it = contentProviderUtils.getTrackPointIterator(trackId, null)) {
|
||||
while (it.hasNext()) {
|
||||
TrackPoint trackPoint = it.next();
|
||||
assertNotNull(trackPoint);
|
||||
@@ -165,7 +164,7 @@ public class CustomContentProviderUtilsTest {
|
||||
// Load all inserted trackPoints.
|
||||
TrackPoint.Id lastPointId = null;
|
||||
int counter = 0;
|
||||
try (AutoCloseableIterator<TrackPoint> it = contentProviderUtils.getTrackPointIterator(id, null)) {
|
||||
try (TrackPointIterator it = contentProviderUtils.getTrackPointIterator(id, null)) {
|
||||
while (it.hasNext()) {
|
||||
TrackPoint trackPoint = it.next();
|
||||
lastPointId = trackPoint.getId();
|
||||
@@ -852,7 +851,7 @@ public class CustomContentProviderUtilsTest {
|
||||
TrackPoint.Id startTrackPointId = trackpointIds.get(0);
|
||||
|
||||
// when
|
||||
AutoCloseableIterator<TrackPoint> trackPointIterator = contentProviderUtils.getTrackPointIterator(trackId, trackpointIds.get(0));
|
||||
TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointIterator(trackId, trackpointIds.get(0));
|
||||
|
||||
// then
|
||||
for (int i = 0; i < trackpointIds.size(); i++) {
|
||||
@@ -1210,7 +1209,7 @@ public class CustomContentProviderUtilsTest {
|
||||
}
|
||||
|
||||
private TrackPoint getLastValidTrackPoint(Track.Id trackId) {
|
||||
try (AutoCloseableIterator<TrackPoint> trackPointsCursor = contentProviderUtils.getTrackPointIterator(trackId, null)) {
|
||||
try (TrackPointIterator trackPointsCursor = contentProviderUtils.getTrackPointIterator(trackId, null)) {
|
||||
List<TrackPoint> trackpoints = new ArrayList<>();
|
||||
while (trackPointsCursor.hasNext())
|
||||
trackpoints.add(trackPointsCursor.next());
|
||||
|
||||
@@ -45,7 +45,6 @@ import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.data.TrackListIterator;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.databinding.TrackListBinding;
|
||||
import de.dennisguse.opentracks.sensors.GpsStatusValue;
|
||||
@@ -63,7 +62,6 @@ import de.dennisguse.opentracks.ui.aggregatedStatistics.ConfirmDeleteDialogFragm
|
||||
import de.dennisguse.opentracks.ui.markers.MarkerListActivity;
|
||||
import de.dennisguse.opentracks.ui.util.ActivityUtils;
|
||||
import de.dennisguse.opentracks.ui.util.RecyclerViewSwipeDeleteCallback;
|
||||
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
import de.dennisguse.opentracks.util.IntentDashboardUtils;
|
||||
import de.dennisguse.opentracks.util.IntentUtils;
|
||||
import de.dennisguse.opentracks.util.PermissionRequester;
|
||||
@@ -312,9 +310,7 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
|
||||
|
||||
viewBinding.trackListToolbar.setTitle(Objects.requireNonNullElseGet(searchQuery, () -> getString(R.string.app_name)));
|
||||
|
||||
AutoCloseableIterator<TrackListIterator.Item> tracks = new ContentProviderUtils(this).searchTracks(searchQuery);
|
||||
|
||||
adapter.swapData(tracks);
|
||||
adapter.swapData(new ContentProviderUtils(this).searchTracks(searchQuery));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -56,7 +56,6 @@ import de.dennisguse.opentracks.data.tables.TrackPointsColumns;
|
||||
import de.dennisguse.opentracks.data.tables.TracksColumns;
|
||||
import de.dennisguse.opentracks.stats.SensorStatistics;
|
||||
import de.dennisguse.opentracks.ui.markers.MarkerUtils;
|
||||
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
import de.dennisguse.opentracks.util.FileUtils;
|
||||
|
||||
/**
|
||||
@@ -180,7 +179,7 @@ public class ContentProviderUtils {
|
||||
return tracks;
|
||||
}
|
||||
|
||||
public AutoCloseableIterator<TrackListIterator.Item> searchTracks(String searchQuery) {
|
||||
public TrackListIterator searchTracks(String searchQuery) {
|
||||
// Needed, because MARKER_COUNT is a virtual column and has to be explicitly requested.
|
||||
final String[] PROJECTION = new String[]{
|
||||
TracksColumns._ID,
|
||||
@@ -401,11 +400,11 @@ public class ContentProviderUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
public AutoCloseableIterator<Marker> getMarkerIterator(@NonNull Track.Id trackId) {
|
||||
public MarkerIterator getMarkerIterator(@NonNull Track.Id trackId) {
|
||||
return new MarkerIterator(this, trackId, -1);
|
||||
}
|
||||
|
||||
public AutoCloseableIterator<Marker> getMarkerIterator(@NonNull Track.Id trackId, int maxCount) {
|
||||
public MarkerIterator getMarkerIterator(@NonNull Track.Id trackId, int maxCount) {
|
||||
return new MarkerIterator(this, trackId, maxCount);
|
||||
}
|
||||
|
||||
@@ -674,7 +673,7 @@ public class ContentProviderUtils {
|
||||
* @param trackId the track id
|
||||
* @param startTrackPointId the starting trackPoint id. `null` to ignore
|
||||
*/
|
||||
public AutoCloseableIterator<TrackPoint> getTrackPointIterator(Track.Id trackId, TrackPoint.Id startTrackPointId) {
|
||||
public TrackPointIterator getTrackPointIterator(Track.Id trackId, TrackPoint.Id startTrackPointId) {
|
||||
return new TrackPointIterator(this, trackId, startTrackPointId);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,6 @@ package de.dennisguse.opentracks.data;
|
||||
import android.database.Cursor;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import de.dennisguse.opentracks.data.models.Marker;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
@@ -13,20 +10,16 @@ import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
|
||||
public class MarkerIterator extends AutoCloseableIterator<Marker> {
|
||||
|
||||
private static final String TAG = MarkerIterator.class.getSimpleName();
|
||||
|
||||
private final ContentProviderUtils contentProviderUtils;
|
||||
private Cursor cursor;
|
||||
|
||||
MarkerIterator(ContentProviderUtils contentProviderUtils, Cursor cursor) {
|
||||
super(cursor);
|
||||
this.contentProviderUtils = contentProviderUtils;
|
||||
this.cursor = cursor;
|
||||
}
|
||||
|
||||
MarkerIterator(ContentProviderUtils contentProviderUtils, Track.Id trackId, int maxCount) {
|
||||
super(contentProviderUtils.getMarkerCursor(trackId, maxCount));
|
||||
this.contentProviderUtils = contentProviderUtils;
|
||||
|
||||
cursor = contentProviderUtils.getMarkerCursor(trackId, maxCount);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -34,49 +27,4 @@ public class MarkerIterator extends AutoCloseableIterator<Marker> {
|
||||
public Marker get() {
|
||||
return contentProviderUtils.createMarker(cursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (cursor == null) {
|
||||
return false;
|
||||
}
|
||||
return !cursor.isLast() && !cursor.isAfterLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Marker next() {
|
||||
if (cursor == null || !cursor.moveToNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
return get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPosition() {
|
||||
return cursor.getPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToPosition(int position) {
|
||||
return cursor.moveToPosition(position);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public int getCount() {
|
||||
return cursor.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
cursor = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,6 @@ import de.dennisguse.opentracks.services.RecordingStatus;
|
||||
import de.dennisguse.opentracks.services.TrackRecordingService;
|
||||
import de.dennisguse.opentracks.services.handlers.AltitudeCorrectionManager;
|
||||
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
|
||||
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
|
||||
/**
|
||||
* Track data hub.
|
||||
@@ -279,7 +278,7 @@ public class TrackDataHub {
|
||||
}
|
||||
|
||||
TrackPoint trackPoint = null;
|
||||
try (AutoCloseableIterator<TrackPoint> trackPointIterator = contentProviderUtils.getTrackPointIterator(selectedTrackId, next)) {
|
||||
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointIterator(selectedTrackId, next)) {
|
||||
long numTotalPoints = trackPointIterator.getCount();
|
||||
int samplingFrequency = 1 + (int) (numTotalPoints / targetNumPoints);
|
||||
|
||||
|
||||
@@ -3,12 +3,10 @@ package de.dennisguse.opentracks.data;
|
||||
import android.database.Cursor;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import de.dennisguse.opentracks.data.models.ActivityType;
|
||||
import de.dennisguse.opentracks.data.models.Distance;
|
||||
@@ -18,12 +16,8 @@ import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
|
||||
public class TrackListIterator extends AutoCloseableIterator<TrackListIterator.Item> {
|
||||
|
||||
private static final String TAG = TrackListIterator.class.getSimpleName();
|
||||
|
||||
private Cursor cursor;
|
||||
|
||||
TrackListIterator(Cursor cursor) {
|
||||
this.cursor = cursor;
|
||||
super(cursor);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -54,51 +48,6 @@ public class TrackListIterator extends AutoCloseableIterator<TrackListIterator.I
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (cursor == null) {
|
||||
return false;
|
||||
}
|
||||
return !cursor.isLast() && !cursor.isAfterLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Item next() {
|
||||
if (cursor == null || !cursor.moveToNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
return get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPosition() {
|
||||
return cursor.getPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToPosition(int position) {
|
||||
return cursor.moveToPosition(position);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public int getCount() {
|
||||
return cursor.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
cursor = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public record Item(
|
||||
@NonNull
|
||||
Track.Id id,
|
||||
@@ -128,7 +77,6 @@ public class TrackListIterator extends AutoCloseableIterator<TrackListIterator.I
|
||||
Distance totalDistance,
|
||||
|
||||
int markerCount
|
||||
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -1,78 +1,23 @@
|
||||
package de.dennisguse.opentracks.data;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
|
||||
/**
|
||||
* A lightweight wrapper around the original {@link Cursor}.
|
||||
*/
|
||||
class TrackPointIterator extends AutoCloseableIterator<TrackPoint> {
|
||||
public class TrackPointIterator extends AutoCloseableIterator<TrackPoint> {
|
||||
|
||||
private static final String TAG = TrackPointIterator.class.getSimpleName();
|
||||
private final CachedTrackPointsIndexes indexes;
|
||||
private Cursor cursor;
|
||||
|
||||
TrackPointIterator(ContentProviderUtils contentProviderUtils, Track.Id trackId, TrackPoint.Id startTrackPointId) {
|
||||
cursor = contentProviderUtils.getTrackPointCursor(trackId, startTrackPointId);
|
||||
super(contentProviderUtils.getTrackPointCursor(trackId, startTrackPointId));
|
||||
indexes = new CachedTrackPointsIndexes(cursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (cursor == null) {
|
||||
return false;
|
||||
}
|
||||
return !cursor.isLast() && !cursor.isAfterLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public TrackPoint get() {
|
||||
return ContentProviderUtils.fillTrackPoint(cursor, indexes);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public TrackPoint next() {
|
||||
if (cursor == null || !cursor.moveToNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
return get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPosition() {
|
||||
return cursor.getPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToPosition(int position) {
|
||||
return cursor.moveToPosition(position);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public int getCount() {
|
||||
return cursor.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
cursor = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -28,10 +28,10 @@ import java.util.Locale;
|
||||
import java.util.function.Function;
|
||||
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.data.TrackPointIterator;
|
||||
import de.dennisguse.opentracks.data.models.Marker;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
import de.dennisguse.opentracks.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -131,7 +131,7 @@ public class CSVTrackExporter implements TrackExporter {
|
||||
}
|
||||
|
||||
private void writeTrackPoints(List<Column> columns, Track track) throws InterruptedException {
|
||||
try (AutoCloseableIterator<TrackPoint> trackPointIterator = contentProviderUtils.getTrackPointIterator(track.id(), null)) {
|
||||
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointIterator(track.id(), null)) {
|
||||
while (trackPointIterator.hasNext()) {
|
||||
if (Thread.interrupted()) throw new InterruptedException();
|
||||
|
||||
|
||||
@@ -33,13 +33,14 @@ import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.data.MarkerIterator;
|
||||
import de.dennisguse.opentracks.data.TrackPointIterator;
|
||||
import de.dennisguse.opentracks.data.models.Distance;
|
||||
import de.dennisguse.opentracks.data.models.Marker;
|
||||
import de.dennisguse.opentracks.data.models.Position;
|
||||
import de.dennisguse.opentracks.data.models.Statistics;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
import de.dennisguse.opentracks.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -128,7 +129,7 @@ public class GPXTrackExporter implements TrackExporter {
|
||||
|
||||
LinkedList<TrackPoint> sensorPoints = new LinkedList<>();
|
||||
|
||||
try (AutoCloseableIterator<TrackPoint> trackPointIterator = contentProviderUtils.getTrackPointIterator(track.id(), null)) {
|
||||
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointIterator(track.id(), null)) {
|
||||
while (trackPointIterator.hasNext()) {
|
||||
if (Thread.interrupted()) throw new InterruptedException();
|
||||
|
||||
@@ -238,7 +239,7 @@ public class GPXTrackExporter implements TrackExporter {
|
||||
}
|
||||
|
||||
private void writeMarkers(Track track) throws InterruptedException {
|
||||
try (AutoCloseableIterator<Marker> markerIterator = contentProviderUtils.getMarkerIterator(track.id())) {
|
||||
try (MarkerIterator markerIterator = contentProviderUtils.getMarkerIterator(track.id())) {
|
||||
while (markerIterator.hasNext()) {
|
||||
if (Thread.interrupted()) throw new InterruptedException();
|
||||
|
||||
|
||||
@@ -35,13 +35,14 @@ import java.util.Objects;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.data.MarkerIterator;
|
||||
import de.dennisguse.opentracks.data.TrackPointIterator;
|
||||
import de.dennisguse.opentracks.data.models.ActivityType;
|
||||
import de.dennisguse.opentracks.data.models.Marker;
|
||||
import de.dennisguse.opentracks.data.models.Position;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
import de.dennisguse.opentracks.ui.markers.MarkerUtils;
|
||||
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
import de.dennisguse.opentracks.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -135,7 +136,7 @@ public class KMLTrackExporter implements TrackExporter {
|
||||
|
||||
private void writeMarkers(Track track) throws InterruptedException {
|
||||
boolean hasMarkers = false;
|
||||
try (AutoCloseableIterator<Marker> markerIterator = contentProviderUtils.getMarkerIterator(track.id())) {
|
||||
try (MarkerIterator markerIterator = contentProviderUtils.getMarkerIterator(track.id())) {
|
||||
while (markerIterator.hasNext()) {
|
||||
if (Thread.interrupted()) throw new InterruptedException();
|
||||
|
||||
@@ -156,7 +157,7 @@ public class KMLTrackExporter implements TrackExporter {
|
||||
boolean wroteTrack = false;
|
||||
boolean wroteSegment = false;
|
||||
|
||||
try (AutoCloseableIterator<TrackPoint> trackPointIterator = contentProviderUtils.getTrackPointIterator(track.id(), null)) {
|
||||
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointIterator(track.id(), null)) {
|
||||
while (trackPointIterator.hasNext()) {
|
||||
if (Thread.interrupted()) throw new InterruptedException();
|
||||
|
||||
|
||||
@@ -32,10 +32,10 @@ import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.data.MarkerIterator;
|
||||
import de.dennisguse.opentracks.data.models.Marker;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.ui.markers.MarkerUtils;
|
||||
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
import de.dennisguse.opentracks.util.FileUtils;
|
||||
|
||||
/**
|
||||
@@ -89,7 +89,7 @@ public class KMZTrackExporter implements TrackExporter {
|
||||
|
||||
private void addImages(Context context, List<Track> tracks, ZipOutputStream zipOutputStream) throws InterruptedException, IOException {
|
||||
for (Track track : tracks) {
|
||||
try (AutoCloseableIterator<Marker> markerIterator = contentProviderUtils.getMarkerIterator(track.id())) {
|
||||
try (MarkerIterator markerIterator = contentProviderUtils.getMarkerIterator(track.id())) {
|
||||
while (markerIterator.hasNext()) {
|
||||
if (Thread.interrupted()) throw new InterruptedException();
|
||||
|
||||
|
||||
@@ -35,9 +35,8 @@ import java.util.zip.ZipInputStream;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.data.models.Marker;
|
||||
import de.dennisguse.opentracks.data.MarkerIterator;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
import de.dennisguse.opentracks.util.FileUtils;
|
||||
|
||||
/**
|
||||
@@ -189,7 +188,7 @@ public class KMZTrackImporter {
|
||||
// 1.- Gets all photo names in the markers of the track identified by id.
|
||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context);
|
||||
List<String> photosName = new ArrayList<>();
|
||||
try (AutoCloseableIterator<Marker> markerIterator = new ContentProviderUtils(context).getMarkerIterator(trackId)) {
|
||||
try (MarkerIterator markerIterator = new ContentProviderUtils(context).getMarkerIterator(trackId)) {
|
||||
markerIterator.forEachRemaining(marker -> {
|
||||
if (marker.photoUrl() != null) {
|
||||
String photoUrl = Uri.decode(marker.photoUrl().toString()); //TODO Why Uri.decode()?
|
||||
|
||||
@@ -13,6 +13,7 @@ import java.time.Instant;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -134,15 +135,7 @@ public class TrackImporter {
|
||||
trackData.uuid = UUID.randomUUID();
|
||||
}
|
||||
|
||||
trackPoints.sort((o1, o2) -> {
|
||||
if (o1.getTime().isBefore(o2.getTime())) {
|
||||
return -1;
|
||||
}
|
||||
if (o1.getTime().isAfter(o2.getTime())) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
trackPoints.sort(Comparator.comparing(TrackPoint::getTime));
|
||||
|
||||
adjustTrackPoints();
|
||||
|
||||
|
||||
+2
-2
@@ -30,6 +30,7 @@ import java.util.List;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.data.TrackPointIterator;
|
||||
import de.dennisguse.opentracks.data.models.Distance;
|
||||
import de.dennisguse.opentracks.data.models.Statistics;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
@@ -37,7 +38,6 @@ import de.dennisguse.opentracks.services.RecordingData;
|
||||
import de.dennisguse.opentracks.settings.PreferencesUtils;
|
||||
import de.dennisguse.opentracks.stats.SensorStatistics;
|
||||
import de.dennisguse.opentracks.ui.intervals.IntervalStatisticsUpdater;
|
||||
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
|
||||
/**
|
||||
* Execute a periodic task on a time or distance schedule.
|
||||
@@ -149,7 +149,7 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe
|
||||
}
|
||||
|
||||
//TODO Avoid reloading (some) TrackPoints just to announce the last interval.
|
||||
try (AutoCloseableIterator<TrackPoint> trackPointIterator = contentProviderUtils.getTrackPointIterator(data.track().id(), startTrackPointId)) {
|
||||
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointIterator(data.track().id(), startTrackPointId)) {
|
||||
startTrackPointId = intervalStatistics.addTrackPoints(trackPointIterator);
|
||||
Statistics lastInterval = intervalStatistics.getLastInterval();
|
||||
SensorStatistics sensorStatistics = null;
|
||||
|
||||
@@ -27,7 +27,6 @@ import de.dennisguse.opentracks.services.RecordingStatus;
|
||||
import de.dennisguse.opentracks.settings.UnitSystem;
|
||||
import de.dennisguse.opentracks.ui.util.ActivityUtils;
|
||||
import de.dennisguse.opentracks.ui.util.ListItemUtils;
|
||||
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
import de.dennisguse.opentracks.util.IntentUtils;
|
||||
|
||||
public class TrackListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements ActionMode.Callback {
|
||||
@@ -39,7 +38,7 @@ public class TrackListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
private final SparseBooleanArray selection = new SparseBooleanArray();
|
||||
private RecordingStatus recordingStatus;
|
||||
private UnitSystem unitSystem;
|
||||
private AutoCloseableIterator<TrackListIterator.Item> cursor;
|
||||
private TrackListIterator cursor;
|
||||
private boolean selectionMode = false;
|
||||
private ActivityUtils.ContextualActionModeCallback actionModeCallback;
|
||||
private ActionMode actionMode;
|
||||
@@ -85,7 +84,7 @@ public class TrackListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
return cursor.getCount();
|
||||
}
|
||||
|
||||
public void swapData(AutoCloseableIterator<TrackListIterator.Item> cursor) {
|
||||
public void swapData(TrackListIterator cursor) {
|
||||
this.cursor = cursor;
|
||||
this.notifyDataSetChanged();
|
||||
}
|
||||
@@ -176,7 +175,7 @@ public class TrackListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||
}
|
||||
|
||||
|
||||
public void bind(AutoCloseableIterator<TrackListIterator.Item> cursor) {
|
||||
public void bind(TrackListIterator cursor) {
|
||||
TrackListIterator.Item tracksListItem = cursor.get();
|
||||
trackId = tracksListItem.id();
|
||||
|
||||
|
||||
@@ -17,13 +17,13 @@ import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.data.TrackPointIterator;
|
||||
import de.dennisguse.opentracks.data.models.Distance;
|
||||
import de.dennisguse.opentracks.data.models.Statistics;
|
||||
import de.dennisguse.opentracks.data.models.Track;
|
||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
||||
import de.dennisguse.opentracks.data.tables.TrackPointsColumns;
|
||||
import de.dennisguse.opentracks.settings.UnitSystem;
|
||||
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
|
||||
/**
|
||||
* This model is used to load intervals for a track.
|
||||
@@ -93,7 +93,7 @@ public class IntervalStatisticsModel extends AndroidViewModel {
|
||||
private void loadIntervalStatistics(Track.Id trackId) {
|
||||
executor.execute(() -> {
|
||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(getApplication());
|
||||
try (AutoCloseableIterator<TrackPoint> trackPointIterator = contentProviderUtils.getTrackPointIterator(trackId, lastTrackPointId)) {
|
||||
try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointIterator(trackId, lastTrackPointId)) {
|
||||
lastTrackPointId = intervalStatistics.addTrackPoints(trackPointIterator);
|
||||
intervalsLiveData.postValue(intervalStatistics.getIntervalList());
|
||||
}
|
||||
|
||||
@@ -30,10 +30,10 @@ import androidx.viewpager2.widget.ViewPager2;
|
||||
import de.dennisguse.opentracks.AbstractActivity;
|
||||
import de.dennisguse.opentracks.R;
|
||||
import de.dennisguse.opentracks.data.ContentProviderUtils;
|
||||
import de.dennisguse.opentracks.data.MarkerIterator;
|
||||
import de.dennisguse.opentracks.data.models.Marker;
|
||||
import de.dennisguse.opentracks.databinding.MarkerDetailActivityBinding;
|
||||
import de.dennisguse.opentracks.ui.markers.DeleteMarkerDialogFragment.DeleteMarkerCaller;
|
||||
import de.dennisguse.opentracks.util.AutoCloseableIterator;
|
||||
|
||||
/**
|
||||
* An activity to display marker detail info.
|
||||
@@ -50,7 +50,7 @@ public class MarkerDetailActivity extends AbstractActivity implements DeleteMark
|
||||
|
||||
private MarkerDetailActivityBinding viewBinding;
|
||||
|
||||
private AutoCloseableIterator<Marker> markerAutoCloseableIterator;
|
||||
private MarkerIterator markerIterator;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle bundle) {
|
||||
@@ -66,15 +66,15 @@ public class MarkerDetailActivity extends AbstractActivity implements DeleteMark
|
||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(this);
|
||||
Marker marker = contentProviderUtils.getMarker(markerId);
|
||||
|
||||
markerAutoCloseableIterator = contentProviderUtils.getMarkerIterator(marker.trackId());
|
||||
if (markerAutoCloseableIterator == null) {
|
||||
markerIterator = contentProviderUtils.getMarkerIterator(marker.trackId());
|
||||
if (markerIterator == null) {
|
||||
finish();
|
||||
}
|
||||
|
||||
int markerIndex = -1;
|
||||
while (markerAutoCloseableIterator.hasNext()) {
|
||||
if (markerId.equals(markerAutoCloseableIterator.next().id())) {
|
||||
markerIndex = markerAutoCloseableIterator.getPosition();
|
||||
while (markerIterator.hasNext()) {
|
||||
if (markerId.equals(markerIterator.next().id())) {
|
||||
markerIndex = markerIterator.getPosition();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -104,8 +104,8 @@ public class MarkerDetailActivity extends AbstractActivity implements DeleteMark
|
||||
super.onDestroy();
|
||||
viewBinding = null;
|
||||
|
||||
if (markerAutoCloseableIterator != null) markerAutoCloseableIterator.close();
|
||||
markerAutoCloseableIterator = null;
|
||||
if (markerIterator != null) markerIterator.close();
|
||||
markerIterator = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,18 +122,18 @@ public class MarkerDetailActivity extends AbstractActivity implements DeleteMark
|
||||
@Override
|
||||
@NonNull
|
||||
public Fragment createFragment(int position) {
|
||||
markerAutoCloseableIterator.moveToPosition(position);
|
||||
return MarkerDetailFragment.newInstance(markerAutoCloseableIterator.get(position).id());
|
||||
markerIterator.moveToPosition(position);
|
||||
return MarkerDetailFragment.newInstance(markerIterator.get(position).id());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return markerAutoCloseableIterator.getCount();
|
||||
return markerIterator.getCount();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CharSequence getPageTitle(int position) {
|
||||
return getString(R.string.marker_detail_title, position + 1, getItemCount(), markerAutoCloseableIterator.get().name());
|
||||
return getString(R.string.marker_detail_title, position + 1, getItemCount(), markerIterator.get().name());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,70 @@
|
||||
package de.dennisguse.opentracks.util;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
//TODO All children use a cursor. Move this shared functionality here.
|
||||
public abstract class AutoCloseableIterator<T> implements Iterator<T>, AutoCloseable {
|
||||
|
||||
/**
|
||||
* Override: AutoClosable.close() throws Exception.
|
||||
*/
|
||||
public abstract void close();
|
||||
protected Cursor cursor;
|
||||
|
||||
public abstract int getPosition();
|
||||
public AutoCloseableIterator(Cursor cursor) {
|
||||
this.cursor = cursor;
|
||||
}
|
||||
|
||||
public abstract boolean moveToPosition(int position);
|
||||
@Override
|
||||
@NonNull
|
||||
public final T next() {
|
||||
if (cursor == null || !cursor.moveToNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
return get();
|
||||
}
|
||||
|
||||
public final int getPosition() {
|
||||
return cursor.getPosition();
|
||||
}
|
||||
|
||||
public final boolean moveToPosition(int position) {
|
||||
return cursor.moveToPosition(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean hasNext() {
|
||||
if (cursor == null) {
|
||||
return false;
|
||||
}
|
||||
return !cursor.isLast() && !cursor.isAfterLast();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public abstract T get();
|
||||
|
||||
@NonNull
|
||||
public T get(int position) {
|
||||
public final T get(int position) {
|
||||
moveToPosition(position);
|
||||
return get();
|
||||
}
|
||||
|
||||
public abstract int getCount();
|
||||
@VisibleForTesting
|
||||
public final int getCount() {
|
||||
return cursor.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void close() {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
cursor = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user