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