From 901cffee9705a9c1c99b00890b238d8a366d1826 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Thu, 26 Mar 2020 22:52:42 +0100 Subject: [PATCH] Use TrackPoint instead of Location (and omit casting). --- .../dennisguse/opentracks/TrackStubUtils.java | 25 +-- .../opentracks/content/data/TestDataUtil.java | 20 +- .../CustomContentProviderUtilsTest.java | 64 +++--- .../fragments/ChartFragmentTest.java | 22 +- .../AbstractTestFileTrackImporter.java | 22 +- .../io/file/importer/ExportImportTest.java | 10 +- .../importer/GpxFileTrackImporterTest.java | 21 +- .../importer/KmlFileTrackImporterTest.java | 17 +- ...cordingServiceNotificationManagerTest.java | 5 +- .../services/TrackRecordingServiceTest.java | 22 +- .../TrackRecordingServiceTestLooper.java | 18 +- .../opentracks/content/TrackDataHub.java | 10 +- .../opentracks/content/TrackDataListener.java | 13 +- .../opentracks/content/data/Track.java | 16 +- .../opentracks/content/data/TrackPoint.java | 18 ++ .../provider/ContentProviderUtils.java | 193 +++++++++--------- .../content/provider/TrackPointFactory.java | 2 +- .../content/provider/TrackPointIterator.java | 2 +- .../opentracks/fragments/ChartFragment.java | 21 +- .../opentracks/fragments/StatsFragment.java | 32 +-- .../io/file/exporter/FileTrackExporter.java | 59 +++--- .../io/file/exporter/GpxTrackWriter.java | 15 +- .../io/file/exporter/KmlTrackWriter.java | 24 +-- .../file/exporter/TrackExporterListener.java | 4 +- .../io/file/exporter/TrackWriter.java | 29 ++- .../importer/AbstractFileTrackImporter.java | 77 +++---- .../file/importer/GpxFileTrackImporter.java | 8 +- .../file/importer/KmlFileTrackImporter.java | 17 +- .../services/TrackRecordingService.java | 95 ++++----- .../services/TrackRecordingServiceBinder.java | 7 +- .../TrackRecordingServiceInterface.java | 7 +- .../stats/TripStatisticsUpdater.java | 49 ++--- .../opentracks/util/LocationUtils.java | 19 +- 33 files changed, 473 insertions(+), 490 deletions(-) diff --git a/src/androidTest/java/de/dennisguse/opentracks/TrackStubUtils.java b/src/androidTest/java/de/dennisguse/opentracks/TrackStubUtils.java index e4b2cc2f1..bfc34064b 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/TrackStubUtils.java +++ b/src/androidTest/java/de/dennisguse/opentracks/TrackStubUtils.java @@ -16,8 +16,6 @@ package de.dennisguse.opentracks; -import android.location.Location; - import de.dennisguse.opentracks.content.data.Track; import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.sensor.SensorDataSet; @@ -49,7 +47,7 @@ public class TrackStubUtils { public static Track createTrack(int numberOfLocations) { Track track = new Track(); for (int i = 0; i < numberOfLocations; i++) { - track.addLocation(createSensorDataSetLocation(INITIAL_LATITUDE + i * DIFFERENCE, INITIAL_LONGITUDE + i * DIFFERENCE, INITIAL_ALTITUDE + i * DIFFERENCE)); + track.addTrackPoint(createSensorDataSetLocation(INITIAL_LATITUDE + i * DIFFERENCE, INITIAL_LONGITUDE + i * DIFFERENCE, INITIAL_ALTITUDE + i * DIFFERENCE)); } return track; @@ -70,17 +68,16 @@ public class TrackStubUtils { * @return a SensorDataSetLocation stub. */ private static TrackPoint createSensorDataSetLocation(double latitude, double longitude, double altitude) { - // Initial Location - Location loc = new Location(LOCATION_PROVIDER); - loc.setLatitude(latitude); - loc.setLongitude(longitude); - loc.setAltitude(altitude); - loc.setAccuracy(INITIAL_ACCURACY); - loc.setSpeed(INITIAL_SPEED); - loc.setTime(INITIAL_TIME); - loc.setBearing(INITIAL_BEARING); - SensorDataSet sd = new SensorDataSet(Float.NaN, Float.NaN); + TrackPoint trackPoint = new TrackPoint(LOCATION_PROVIDER); + trackPoint.setLatitude(latitude); + trackPoint.setLongitude(longitude); + trackPoint.setAltitude(altitude); + trackPoint.setAccuracy(INITIAL_ACCURACY); + trackPoint.setSpeed(INITIAL_SPEED); + trackPoint.setTime(INITIAL_TIME); + trackPoint.setBearing(INITIAL_BEARING); + trackPoint.setSensorDataSet(new SensorDataSet(Float.NaN, Float.NaN)); - return new TrackPoint(loc, sd); + return trackPoint; } } diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java index 5791166f9..6e6d8bb2d 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java +++ b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java @@ -1,7 +1,5 @@ package de.dennisguse.opentracks.content.data; -import android.location.Location; - public class TestDataUtil { public static final double INITIAL_LATITUDE = 37.0; @@ -20,7 +18,7 @@ public class TestDataUtil { track.setId(id); track.setName("Test: " + id); for (int i = 0; i < numPoints; i++) { - track.addLocation(createLocation(i)); + track.addTrackPoint(createTrackPoint(i)); } return track; } @@ -31,13 +29,13 @@ public class TestDataUtil { * @param i the index to set the value of location. * @return created location */ - public static Location createLocation(int i) { - Location loc = new Location("test"); - loc.setLatitude(INITIAL_LATITUDE + (double) i / 10000.0); - loc.setLongitude(INITIAL_LONGITUDE - (double) i / 10000.0); - loc.setAccuracy((float) i / 100.0f); - loc.setAltitude(i * ALTITUDE_INTERVAL); - loc.setTime(i + 1); - return loc; + public static TrackPoint createTrackPoint(int i) { + TrackPoint trackpoint = new TrackPoint("test"); + trackpoint.setLatitude(INITIAL_LATITUDE + (double) i / 10000.0); + trackpoint.setLongitude(INITIAL_LONGITUDE - (double) i / 10000.0); + trackpoint.setAccuracy((float) i / 100.0f); + trackpoint.setAltitude(i * ALTITUDE_INTERVAL); + trackpoint.setTime(i + 1); + return trackpoint; } } 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 5f07e6412..f7cb0f517 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/content/provider/CustomContentProviderUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/content/provider/CustomContentProviderUtilsTest.java @@ -85,7 +85,7 @@ public class CustomContentProviderUtilsTest { final AtomicInteger counter = new AtomicInteger(); testIterator(1, 15, 4, false, new TrackPointFactory() { @Override - public TrackPoint createLocation() { + public TrackPoint create() { counter.incrementAndGet(); return location; } @@ -133,13 +133,13 @@ public class CustomContentProviderUtilsTest { testIterator(1, 20000, 2000, false, TrackPointFactory.DEFAULT_LOCATION_FACTORY); } - private List testIterator(long trackId, int numPoints, int batchSize, boolean descending, TrackPointFactory trackPointFactory) { + private List testIterator(long trackId, int numPoints, int batchSize, boolean descending, TrackPointFactory trackPointFactory) { long lastPointId = initializeTrack(trackId, numPoints); contentProviderUtils.setDefaultCursorBatchSize(batchSize); - List locations = new ArrayList(numPoints); + List locations = new ArrayList<>(numPoints); try (TrackPointIterator it = contentProviderUtils.getTrackPointLocationIterator(trackId, -1L, descending, trackPointFactory)) { while (it.hasNext()) { - Location loc = it.next(); + TrackPoint loc = it.next(); Assert.assertNotNull(loc); locations.add(loc); // Make sure the IDs are returned in the right order. @@ -159,18 +159,18 @@ public class CustomContentProviderUtilsTest { track = contentProviderUtils.getTrack(id); Assert.assertNotNull(track); - Location[] locations = new Location[numPoints]; + TrackPoint[] trackPoints = new TrackPoint[numPoints]; for (int i = 0; i < numPoints; ++i) { - Location loc = new Location("test"); + TrackPoint loc = new TrackPoint("test"); loc.setLatitude(37.0 + (double) i / 10000.0); loc.setLongitude(57.0 - (double) i / 10000.0); loc.setAccuracy((float) i / 100.0f); loc.setAltitude(i * 2.5); - locations[i] = loc; + trackPoints[i] = loc; } - contentProviderUtils.bulkInsertTrackPoint(locations, numPoints, id); + contentProviderUtils.bulkInsertTrackPoint(trackPoints, numPoints, id); - // Load all inserted locations. + // Load all inserted trackPoints. long lastPointId = -1; int counter = 0; try (TrackPointIterator it = contentProviderUtils.getTrackPointLocationIterator(id, -1L, false, TrackPointFactory.DEFAULT_LOCATION_FACTORY)) { @@ -546,7 +546,7 @@ public class CustomContentProviderUtilsTest { } /** - * Tests the method {@link ContentProviderUtils#bulkInsertTrackPoint(Location[], int, long)}. + * Tests the method {@link ContentProviderUtils#bulkInsertTrackPoint(TrackPoint[], int, long)}. */ @Test public void testBulkInsertTrackPoint() { @@ -555,9 +555,9 @@ public class CustomContentProviderUtilsTest { Track track = TestDataUtil.getTrack(trackId, 10); insertTrackWithLocations(track); - contentProviderUtils.bulkInsertTrackPoint(track.getLocations().toArray(new Location[0]), -1, trackId); + contentProviderUtils.bulkInsertTrackPoint(track.getTrackPoints().toArray(new TrackPoint[0]), -1, trackId); Assert.assertEquals(20, contentProviderUtils.getTrackPointCursor(trackId, -1L, 1000, false).getCount()); - contentProviderUtils.bulkInsertTrackPoint(track.getLocations().toArray(new Location[0]), 8, trackId); + contentProviderUtils.bulkInsertTrackPoint(track.getTrackPoints().toArray(new TrackPoint[0]), 8, trackId); Assert.assertEquals(28, contentProviderUtils.getTrackPointCursor(trackId, -1L, 1000, false).getCount()); } @@ -613,7 +613,7 @@ public class CustomContentProviderUtilsTest { byte[] sensor = "Sensor state".getBytes(); when(cursorMock.getBlob(index++)).thenReturn(sensor); - Location location = contentProviderUtils.createTrackPoint(cursorMock); + TrackPoint location = contentProviderUtils.createTrackPoint(cursorMock); Assert.assertEquals(longitude, location.getLongitude(), 0.01); Assert.assertEquals(latitude, location.getLatitude(), 0.01); Assert.assertEquals(time, location.getTime(), 0.01); @@ -622,7 +622,7 @@ public class CustomContentProviderUtilsTest { /** * Tests the method - * {@link ContentProviderUtils#insertTrackPoint(Location, long)}. + * {@link ContentProviderUtils#insertTrackPoint(TrackPoint, long)}. */ @Test public void testInsertTrackPoint() { @@ -631,7 +631,7 @@ public class CustomContentProviderUtilsTest { Track track = TestDataUtil.getTrack(trackId, 10); insertTrackWithLocations(track); - contentProviderUtils.insertTrackPoint(TestDataUtil.createLocation(22), trackId); + contentProviderUtils.insertTrackPoint(TestDataUtil.createTrackPoint(22), trackId); Assert.assertEquals(11, contentProviderUtils.getTrackPointCursor(trackId, -1L, 1000, false).getCount()); } @@ -645,8 +645,8 @@ public class CustomContentProviderUtilsTest { Track track = TestDataUtil.getTrack(trackId, 10); insertTrackWithLocations(track); - Location lastLocation = contentProviderUtils.getLastValidTrackPoint(trackId); - checkLocation(9, lastLocation); + TrackPoint lastTrackPoint = contentProviderUtils.getLastValidTrackPoint(trackId); + checkLocation(9, lastTrackPoint); } /** @@ -659,9 +659,9 @@ public class CustomContentProviderUtilsTest { Track track = TestDataUtil.getTrack(trackId, 10); contentProviderUtils.insertTrack(track); - long[] trackpointIds = new long[track.getLocations().size()]; + long[] trackpointIds = new long[track.getTrackPoints().size()]; for (int i = 0; i < trackpointIds.length; i++) { - trackpointIds[i] = ContentUris.parseId(contentProviderUtils.insertTrackPoint(track.getLocations().get(i), track.getId())); + trackpointIds[i] = ContentUris.parseId(contentProviderUtils.insertTrackPoint(track.getTrackPoints().get(i), track.getId())); } Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackpointIds[1], 5, true); @@ -678,9 +678,9 @@ public class CustomContentProviderUtilsTest { Track track = TestDataUtil.getTrack(trackId, 10); contentProviderUtils.insertTrack(track); - long[] trackpointIds = new long[track.getLocations().size()]; + long[] trackpointIds = new long[track.getTrackPoints().size()]; for (int i = 0; i < trackpointIds.length; i++) { - trackpointIds[i] = ContentUris.parseId(contentProviderUtils.insertTrackPoint(track.getLocations().get(i), track.getId())); + trackpointIds[i] = ContentUris.parseId(contentProviderUtils.insertTrackPoint(track.getTrackPoints().get(i), track.getId())); } Cursor cursor = contentProviderUtils.getTrackPointCursor(trackId, trackpointIds[8], 5, false); @@ -697,21 +697,21 @@ public class CustomContentProviderUtilsTest { Track track = TestDataUtil.getTrack(trackId, 10); contentProviderUtils.insertTrack(track); - long[] trackpointIds = new long[track.getLocations().size()]; + long[] trackpointIds = new long[track.getTrackPoints().size()]; for (int i = 0; i < trackpointIds.length; i++) { - trackpointIds[i] = ContentUris.parseId(contentProviderUtils.insertTrackPoint(track.getLocations().get(i), track.getId())); + trackpointIds[i] = ContentUris.parseId(contentProviderUtils.insertTrackPoint(track.getTrackPoints().get(i), track.getId())); } long startTrackPointId = trackpointIds[9]; - TrackPointIterator locationIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, startTrackPointId, true, TrackPointFactory.DEFAULT_LOCATION_FACTORY); + TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, startTrackPointId, true, TrackPointFactory.DEFAULT_LOCATION_FACTORY); for (int i = 0; i < trackpointIds.length; i++) { - Assert.assertTrue(locationIterator.hasNext()); - Location location = locationIterator.next(); - Assert.assertEquals(startTrackPointId - i, locationIterator.getTrackPointId()); - checkLocation((trackpointIds.length - 1) - i, location); + Assert.assertTrue(trackPointIterator.hasNext()); + TrackPoint trackPoint = trackPointIterator.next(); + Assert.assertEquals(startTrackPointId - i, trackPointIterator.getTrackPointId()); + checkLocation((trackpointIds.length - 1) - i, trackPoint); } - Assert.assertFalse(locationIterator.hasNext()); + Assert.assertFalse(trackPointIterator.hasNext()); } /** @@ -724,9 +724,9 @@ public class CustomContentProviderUtilsTest { Track track = TestDataUtil.getTrack(trackId, 10); contentProviderUtils.insertTrack(track); - long[] trackpointIds = new long[track.getLocations().size()]; + long[] trackpointIds = new long[track.getTrackPoints().size()]; for (int i = 0; i < trackpointIds.length; i++) { - trackpointIds[i] = ContentUris.parseId(contentProviderUtils.insertTrackPoint(track.getLocations().get(i), track.getId())); + trackpointIds[i] = ContentUris.parseId(contentProviderUtils.insertTrackPoint(track.getTrackPoints().get(i), track.getId())); } long startTrackPointId = trackpointIds[0]; @@ -762,7 +762,7 @@ public class CustomContentProviderUtilsTest { */ private void insertTrackWithLocations(Track track) { contentProviderUtils.insertTrack(track); - contentProviderUtils.bulkInsertTrackPoint(track.getLocations().toArray(new Location[0]), track.getLocations().size(), track.getId()); + contentProviderUtils.bulkInsertTrackPoint(track.getTrackPoints().toArray(new TrackPoint[0]), track.getTrackPoints().size(), track.getId()); } @Test diff --git a/src/androidTest/java/de/dennisguse/opentracks/fragments/ChartFragmentTest.java b/src/androidTest/java/de/dennisguse/opentracks/fragments/ChartFragmentTest.java index 70a667b28..9d2333747 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/fragments/ChartFragmentTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/fragments/ChartFragmentTest.java @@ -67,7 +67,7 @@ public class ChartFragmentTest { } /** - * Tests the logic to get the incorrect values of sensor in {@link ChartFragment#fillDataPoint(Location, double[])}. + * Tests the logic to get the incorrect values of sensor in {@link ChartFragment#fillDataPoint(TrackPoint, double[])}. */ @Test public void testFillDataPoint_sensorIncorrect() { @@ -91,7 +91,7 @@ public class ChartFragmentTest { } /** - * Tests the logic to get the correct values of sensor in {@link ChartFragment#fillDataPoint(Location, double[])}. + * Tests the logic to get the correct values of sensor in {@link ChartFragment#fillDataPoint(TrackPoint, double[])}. */ @Test public void testFillDataPoint_sensorCorrect() { @@ -115,7 +115,7 @@ public class ChartFragmentTest { } /** - * Tests the logic to get the value of metric Distance in {@link ChartFragment#fillDataPoint(Location, double[])}. + * Tests the logic to get the value of metric Distance in {@link ChartFragment#fillDataPoint(TrackPoint, double[])}. */ @Test public void testFillDataPoint_distanceMetric() { @@ -156,7 +156,7 @@ public class ChartFragmentTest { } /** - * Tests the logic to get the value of imperial Distance in {@link ChartFragment#fillDataPoint(Location, double[])}. + * Tests the logic to get the value of imperial Distance in {@link ChartFragment#fillDataPoint(TrackPoint, double[])}. */ @Test public void testFillDataPoint_distanceImperial() { @@ -199,7 +199,7 @@ public class ChartFragmentTest { } /** - * Tests the logic to get the values of time in {@link ChartFragment#fillDataPoint(Location, double[])}. + * Tests the logic to get the values of time in {@link ChartFragment#fillDataPoint(TrackPoint, double[])}. */ @Test public void testFillDataPoint_time() { @@ -216,7 +216,7 @@ public class ChartFragmentTest { } /** - * Tests the logic to get the value of elevation in {@link ChartFragment#fillDataPoint(Location, double[])} by one and two points. + * Tests the logic to get the value of elevation in {@link ChartFragment#fillDataPoint(TrackPoint, double[])} by one and two points. */ @Test public void testFillDataPoint_elevation() { @@ -240,7 +240,7 @@ public class ChartFragmentTest { } /** - * Tests the logic to get the value of speed in {@link ChartFragment#fillDataPoint(Location, double[])}. + * Tests the logic to get the value of speed in {@link ChartFragment#fillDataPoint(TrackPoint, double[])}. * In this test, firstly remove all points in memory, and then fill in two points one by one. * The speed values of these points are 129, 130. */ @@ -338,12 +338,12 @@ public class ChartFragmentTest { /** * Helper method to test fillDataPoint. * - * @param location location to fill - * @return data of this location + * @param trackPoint trackPoint to fill + * @return data of this trackPoint */ - private double[] fillDataPointTestHelper(Location location) { + private double[] fillDataPointTestHelper(TrackPoint trackPoint) { double[] point = new double[ChartView.NUM_SERIES + 1]; - chartFragment.fillDataPoint(location, point); + chartFragment.fillDataPoint(trackPoint, point); return point; } } diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/AbstractTestFileTrackImporter.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/AbstractTestFileTrackImporter.java index 47ab81745..9c661e058 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/AbstractTestFileTrackImporter.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/AbstractTestFileTrackImporter.java @@ -18,7 +18,6 @@ package de.dennisguse.opentracks.io.file.importer; import android.content.ContentUris; import android.content.Context; -import android.location.Location; import android.location.LocationManager; import android.net.Uri; @@ -33,6 +32,7 @@ import java.util.Locale; import java.util.SimpleTimeZone; import de.dennisguse.opentracks.content.data.Track; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.TracksColumns; import de.dennisguse.opentracks.content.data.Waypoint; import de.dennisguse.opentracks.content.data.WaypointsColumns; @@ -83,24 +83,24 @@ public abstract class AbstractTestFileTrackImporter { @Mock public ContentProviderUtils contentProviderUtils; - Location createLocation(int index, long time) { - Location location = new Location(LocationManager.GPS_PROVIDER); - location.setLatitude(TRACK_LATITUDE + index); - location.setLongitude(TRACK_LONGITUDE + index); - location.setAltitude(TRACK_ELEVATION + index); - location.setTime(time); - return location; + TrackPoint createTrackPoint(int index, long time) { + TrackPoint trackPoint = new TrackPoint(LocationManager.GPS_PROVIDER); + trackPoint.setLatitude(TRACK_LATITUDE + index); + trackPoint.setLongitude(TRACK_LONGITUDE + index); + trackPoint.setAltitude(TRACK_ELEVATION + index); + trackPoint.setTime(time); + return trackPoint; } /** * Expects the first track point to be added. * - * @param location the location + * @param trackPoint the trackPoint * @param trackId the track id * @param trackPointId the track point id */ - protected void expectFirstTrackPoint(Location location, long trackId, long trackPointId) { - when(contentProviderUtils.bulkInsertTrackPoint(location != null ? (Location[]) any() : (Location[]) any(), eq(1), eq(trackId))).thenReturn(1); + protected void expectFirstTrackPoint(TrackPoint trackPoint, long trackId, long trackPointId) { + when(contentProviderUtils.bulkInsertTrackPoint(trackPoint != null ? (TrackPoint[]) any() : (TrackPoint[]) any(), eq(1), eq(trackId))).thenReturn(1); } /** diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java index 9b0d2cb03..ad07f98b0 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java @@ -1,7 +1,6 @@ package de.dennisguse.opentracks.io.file.importer; import android.content.Context; -import android.location.Location; import android.util.Log; import androidx.test.core.app.ApplicationProvider; @@ -21,6 +20,7 @@ import java.util.List; import de.dennisguse.opentracks.content.data.TestDataUtil; import de.dennisguse.opentracks.content.data.Track; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.Waypoint; import de.dennisguse.opentracks.content.provider.ContentProviderUtils; import de.dennisguse.opentracks.io.file.TrackFileFormat; @@ -57,7 +57,7 @@ public class ExportImportTest { track.setCategory(TRACK_CATEGORY); track.setDescription(TRACK_DESCRIPTION); contentProviderUtils.insertTrack(track); - contentProviderUtils.bulkInsertTrackPoint(track.getLocations().toArray(new Location[0]), track.getLocations().size(), track.getId()); + contentProviderUtils.bulkInsertTrackPoint(track.getTrackPoints().toArray(new TrackPoint[0]), track.getTrackPoints().size(), track.getId()); for (int i = 0; i < 3; i++) { Waypoint waypoint = new Waypoint(); @@ -67,7 +67,7 @@ public class ExportImportTest { waypoint.setIcon("the waypoing icon" + i); waypoint.setPhotoUrl("the photo url" + i); waypoint.setTrackId(trackId); - waypoint.setLocation(track.getLocations().get(i)); + waypoint.setLocation(track.getTrackPoints().get(i)); contentProviderUtils.insertWaypoint(waypoint); waypoints.add(waypoint); @@ -114,7 +114,7 @@ public class ExportImportTest { // 1. track Track importedTrack = contentProviderUtils.getTrack(importTrackId); assertNotNull(importedTrack); - assertEquals(track.getLocations(), importedTrack.getLocations()); + assertEquals(track.getTrackPoints(), importedTrack.getTrackPoints()); assertEquals(track.getCategory(), importedTrack.getCategory()); assertEquals(track.getDescription(), importedTrack.getDescription()); assertEquals(track.getName(), importedTrack.getName()); @@ -184,7 +184,7 @@ public class ExportImportTest { // 1. track Track trackImported = contentProviderUtils.getTrack(importTrackId); assertNotNull(trackImported); - assertEquals(track.getLocations(), trackImported.getLocations()); + assertEquals(track.getTrackPoints(), trackImported.getTrackPoints()); assertEquals(track.getCategory(), trackImported.getCategory()); assertEquals(track.getDescription(), trackImported.getDescription()); assertEquals(track.getName(), trackImported.getName()); diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporterTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporterTest.java index 5ea6bed38..312165386 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporterTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporterTest.java @@ -16,8 +16,6 @@ package de.dennisguse.opentracks.io.file.importer; -import android.location.Location; - import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -28,6 +26,7 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import de.dennisguse.opentracks.content.data.Track; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.util.PreferencesUtils; import static org.mockito.Mockito.any; @@ -85,14 +84,14 @@ public class GpxFileTrackImporterTest extends AbstractTestFileTrackImporter { @Test public void testOneTrackOneSegment() throws Exception { // given - Location location0 = createLocation(0, DATE_FORMAT_0.parse(TRACK_TIME_0).getTime()); - Location location1 = createLocation(1, DATE_FORMAT_1.parse(TRACK_TIME_1).getTime()); + TrackPoint trackPoint0 = createTrackPoint(0, DATE_FORMAT_0.parse(TRACK_TIME_0).getTime()); + TrackPoint trackPoint1 = createTrackPoint(1, DATE_FORMAT_1.parse(TRACK_TIME_1).getTime()); when(contentProviderUtils.insertTrack((Track) any())).thenReturn(TRACK_ID_0_URI); - expectFirstTrackPoint(location0, TRACK_ID_0, TRACK_POINT_ID_0); + expectFirstTrackPoint(trackPoint0, TRACK_ID_0, TRACK_POINT_ID_0); // A flush happens at the end - when(contentProviderUtils.bulkInsertTrackPoint((Location[]) any(), eq(1), eq(TRACK_ID_0))).thenReturn(1); + when(contentProviderUtils.bulkInsertTrackPoint((TrackPoint[]) any(), eq(1), eq(TRACK_ID_0))).thenReturn(1); when(contentProviderUtils.getLastTrackPointId(TRACK_ID_0)).thenReturn(TRACK_POINT_ID_1); when(contentProviderUtils.getTrack(PreferencesUtils.getRecordingTrackId(context))).thenReturn(null); ArgumentCaptor trackCaptor = ArgumentCaptor.forClass(Track.class); @@ -116,12 +115,12 @@ public class GpxFileTrackImporterTest extends AbstractTestFileTrackImporter { @Test public void testOneTrackTwoSegments() throws Exception { // given - Location location0 = createLocation(0, DATE_FORMAT_0.parse(TRACK_TIME_0).getTime()); + TrackPoint trackPoint0 = createTrackPoint(0, DATE_FORMAT_0.parse(TRACK_TIME_0).getTime()); when(contentProviderUtils.insertTrack((Track) any())).thenReturn(TRACK_ID_0_URI); - expectFirstTrackPoint(location0, TRACK_ID_0, TRACK_POINT_ID_0); + expectFirstTrackPoint(trackPoint0, TRACK_ID_0, TRACK_POINT_ID_0); // A flush happens at the end - when(contentProviderUtils.bulkInsertTrackPoint((Location[]) any(), eq(5), eq(TRACK_ID_0))).thenReturn(5); + when(contentProviderUtils.bulkInsertTrackPoint((TrackPoint[]) any(), eq(5), eq(TRACK_ID_0))).thenReturn(5); when(contentProviderUtils.getLastTrackPointId(TRACK_ID_0)).thenReturn(TRACK_POINT_ID_3); when(contentProviderUtils.getTrack(PreferencesUtils.getRecordingTrackId(context))).thenReturn(null); @@ -153,7 +152,7 @@ public class GpxFileTrackImporterTest extends AbstractTestFileTrackImporter { expectFirstTrackPoint(null, TRACK_ID_0, TRACK_POINT_ID_0); // A flush happens at the end - when(contentProviderUtils.bulkInsertTrackPoint((Location[]) any(), eq(5), eq(TRACK_ID_0))).thenReturn(5); + when(contentProviderUtils.bulkInsertTrackPoint((TrackPoint[]) any(), eq(5), eq(TRACK_ID_0))).thenReturn(5); when(contentProviderUtils.getLastTrackPointId(TRACK_ID_0)).thenReturn(TRACK_POINT_ID_3); when(contentProviderUtils.getTrack(PreferencesUtils.getRecordingTrackId(context))).thenReturn(null); @@ -207,7 +206,7 @@ public class GpxFileTrackImporterTest extends AbstractTestFileTrackImporter { when(contentProviderUtils.insertTrack((Track) any())).thenReturn(TRACK_ID_0_URI); // For the following, use StubReturn since we don't care whether they are invoked or not. - when(contentProviderUtils.bulkInsertTrackPoint((Location[]) any(), anyInt(), anyLong())).thenReturn(1); + when(contentProviderUtils.bulkInsertTrackPoint((TrackPoint[]) any(), anyInt(), anyLong())).thenReturn(1); when(contentProviderUtils.getTrack(PreferencesUtils.getRecordingTrackId(context))).thenReturn(null); contentProviderUtils.deleteTrack(context, TRACK_ID_0); diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/KmlFileTrackImporterTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/KmlFileTrackImporterTest.java index 1acd522ac..58635b8cd 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/KmlFileTrackImporterTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/KmlFileTrackImporterTest.java @@ -16,8 +16,6 @@ package de.dennisguse.opentracks.io.file.importer; -import android.location.Location; - import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -28,6 +26,7 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import de.dennisguse.opentracks.content.data.Track; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.util.PreferencesUtils; import static org.mockito.Mockito.any; @@ -69,14 +68,14 @@ public class KmlFileTrackImporterTest extends AbstractTestFileTrackImporter { @Test public void testOneTrackOneSegment() throws Exception { // given - Location location0 = createLocation(0, DATE_FORMAT_0.parse(TRACK_TIME_0).getTime()); - Location location1 = createLocation(1, DATE_FORMAT_1.parse(TRACK_TIME_1).getTime()); + TrackPoint trackPoint0 = createTrackPoint(0, DATE_FORMAT_0.parse(TRACK_TIME_0).getTime()); + TrackPoint trackPointl1 = createTrackPoint(1, DATE_FORMAT_1.parse(TRACK_TIME_1).getTime()); contentProviderUtils.clearTrack(context, TRACK_ID_0); - expectFirstTrackPoint(location0, TRACK_ID_0, TRACK_POINT_ID_0); + expectFirstTrackPoint(trackPoint0, TRACK_ID_0, TRACK_POINT_ID_0); // A flush happens at the end - when(contentProviderUtils.bulkInsertTrackPoint((Location[]) any(), eq(1), eq(TRACK_ID_0))).thenReturn(1); + when(contentProviderUtils.bulkInsertTrackPoint((TrackPoint[]) any(), eq(1), eq(TRACK_ID_0))).thenReturn(1); when(contentProviderUtils.getLastTrackPointId(TRACK_ID_0)).thenReturn(TRACK_POINT_ID_1); when(contentProviderUtils.getTrack(PreferencesUtils.getRecordingTrackId(context))).thenReturn(null); @@ -101,13 +100,13 @@ public class KmlFileTrackImporterTest extends AbstractTestFileTrackImporter { @Test public void testOneTrackTwoSegments() throws Exception { // given - Location location0 = createLocation(0, DATE_FORMAT_0.parse(TRACK_TIME_0).getTime()); + TrackPoint trackPoint0 = createTrackPoint(0, DATE_FORMAT_0.parse(TRACK_TIME_0).getTime()); contentProviderUtils.clearTrack(context, TRACK_ID_0); - expectFirstTrackPoint(location0, TRACK_ID_0, TRACK_POINT_ID_0); + expectFirstTrackPoint(trackPoint0, TRACK_ID_0, TRACK_POINT_ID_0); // A flush happens at the end - when(contentProviderUtils.bulkInsertTrackPoint((Location[]) any(), eq(5), eq(TRACK_ID_0))).thenReturn(5); + when(contentProviderUtils.bulkInsertTrackPoint((TrackPoint[]) any(), eq(5), eq(TRACK_ID_0))).thenReturn(5); when(contentProviderUtils.getLastTrackPointId(TRACK_ID_0)).thenReturn(TRACK_POINT_ID_3); when(contentProviderUtils.getTrack(PreferencesUtils.getRecordingTrackId(context))).thenReturn(null); diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java index 70998fed4..ea348f382 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java @@ -2,7 +2,6 @@ package de.dennisguse.opentracks.services; import android.app.NotificationManager; import android.content.Context; -import android.location.Location; import androidx.core.app.NotificationCompat; import androidx.test.core.app.ApplicationProvider; @@ -12,6 +11,8 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import de.dennisguse.opentracks.content.data.TrackPoint; + import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.times; @@ -24,7 +25,7 @@ public class TrackRecordingServiceNotificationManagerTest { private Context context = ApplicationProvider.getApplicationContext(); @Mock - private Location locationMock; + private TrackPoint locationMock; @Mock private NotificationCompat.Builder notificationCompatBuilder; diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTest.java index 09f7f4c15..023255aea 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTest.java @@ -19,7 +19,6 @@ import android.content.ContentProvider; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; -import android.location.Location; import android.os.IBinder; import androidx.test.core.app.ApplicationProvider; @@ -43,6 +42,7 @@ import java.util.concurrent.TimeoutException; import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.content.data.Track; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.Waypoint; import de.dennisguse.opentracks.content.provider.ContentProviderUtils; import de.dennisguse.opentracks.content.provider.CustomContentProvider; @@ -210,15 +210,15 @@ public class TrackRecordingServiceTest { /** * Inserts a location and waits for 200ms. */ - private void insertLocation(TrackRecordingServiceInterface trackRecordingService) throws InterruptedException { - Location location = new Location("gps"); - location.setLongitude(35.0f); - location.setLatitude(45.0f); - location.setAccuracy(5); - location.setSpeed(10); - location.setTime(System.currentTimeMillis()); - location.setBearing(3.0f); - trackRecordingService.insertTrackPoint(location); + private void insertTrackPoint(TrackRecordingServiceInterface trackRecordingService) throws InterruptedException { + TrackPoint trackPoint = new TrackPoint("gps"); + trackPoint.setLongitude(35.0f); + trackPoint.setLatitude(45.0f); + trackPoint.setAccuracy(5); + trackPoint.setSpeed(10); + trackPoint.setTime(System.currentTimeMillis()); + trackPoint.setBearing(3.0f); + trackRecordingService.insertTrackPoint(trackPoint); Thread.sleep(200); } @@ -239,7 +239,7 @@ public class TrackRecordingServiceTest { TrackRecordingServiceInterface service = ((TrackRecordingServiceInterface) mServiceRule.bindService(createStartIntent(context))); service.startNewTrack(); Assert.assertTrue(service.isRecording()); - insertLocation(service); + insertTrackPoint(service); long trackId = service.getRecordingTrackId(); long waypointId = service.insertWaypoint(null, null, null, null); diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTestLooper.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTestLooper.java index e3d412530..fc12b6fc0 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTestLooper.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTestLooper.java @@ -3,7 +3,6 @@ package de.dennisguse.opentracks.services; import android.content.ContentProvider; import android.content.Context; import android.content.SharedPreferences; -import android.location.Location; import android.os.Looper; import androidx.test.core.app.ApplicationProvider; @@ -26,6 +25,7 @@ import java.util.concurrent.TimeoutException; import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.content.data.Track; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.provider.ContentProviderUtils; import de.dennisguse.opentracks.content.provider.CustomContentProvider; import de.dennisguse.opentracks.stats.TripStatistics; @@ -208,14 +208,14 @@ public class TrackRecordingServiceTestLooper { // Insert a few points, markers and statistics. long startTime = System.currentTimeMillis(); for (int i = 0; i < 30; i++) { - Location location = new Location("gps"); - location.setLongitude(35.0f + i / 10.0f); - location.setLatitude(45.0f - i / 5.0f); - location.setAccuracy(5); - location.setSpeed(10); - location.setTime(startTime + i * 10000); - location.setBearing(3.0f); - service.insertTrackPoint(location); + TrackPoint trackPoint = new TrackPoint("gps"); + trackPoint.setLongitude(35.0f + i / 10.0f); + trackPoint.setLatitude(45.0f - i / 5.0f); + trackPoint.setAccuracy(5); + trackPoint.setSpeed(10); + trackPoint.setTime(startTime + i * 10000); + trackPoint.setBearing(3.0f); + service.insertTrackPoint(trackPoint); if (i % 7 == 0) { service.insertWaypoint(null, null, null, null); diff --git a/src/main/java/de/dennisguse/opentracks/content/TrackDataHub.java b/src/main/java/de/dennisguse/opentracks/content/TrackDataHub.java index 02e68bf09..a685ce6d2 100644 --- a/src/main/java/de/dennisguse/opentracks/content/TrackDataHub.java +++ b/src/main/java/de/dennisguse/opentracks/content/TrackDataHub.java @@ -19,7 +19,6 @@ package de.dennisguse.opentracks.content; import android.content.Context; import android.content.SharedPreferences; import android.database.Cursor; -import android.location.Location; import android.os.Handler; import android.os.HandlerThread; import android.util.Log; @@ -32,6 +31,7 @@ import java.util.Set; import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.content.data.Track; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.Waypoint; import de.dennisguse.opentracks.content.provider.ContentProviderUtils; import de.dennisguse.opentracks.content.provider.TrackPointFactory; @@ -395,7 +395,7 @@ public class TrackDataHub implements DataSourceListener, SharedPreferences.OnSha try (TrackPointIterator locationIterator = contentProviderUtils.getTrackPointLocationIterator(selectedTrackId, localLastSeenLocationId + 1, false, TrackPointFactory.DEFAULT_LOCATION_FACTORY)) { while (locationIterator.hasNext()) { - Location location = locationIterator.next(); + TrackPoint trackPoint = locationIterator.next(); long locationId = locationIterator.getTrackPointId(); // Stop if past the last wanted point @@ -412,18 +412,18 @@ public class TrackDataHub implements DataSourceListener, SharedPreferences.OnSha samplingFrequency = 1 + (int) (numTotalPoints / targetNumPoints); } - if (!LocationUtils.isValidLocation(location)) { //This can be split markers (not anymore supported feature) + if (!LocationUtils.isValidLocation(trackPoint)) { //This can be split markers (not anymore supported feature) includeNextPoint = true; } else { // Also include the last point if the selected track is not recording. if (includeNextPoint || (localNumLoadedPoints % samplingFrequency == 0) || (locationId == lastTrackPointId && !isSelectedTrackRecording())) { includeNextPoint = false; for (TrackDataListener trackDataListener : sampledInListeners) { - trackDataListener.onSampledInTrackPoint(location); + trackDataListener.onSampledInTrackPoint(trackPoint); } } else { for (TrackDataListener trackDataListener : sampledOutListeners) { - trackDataListener.onSampledOutTrackPoint(location); + trackDataListener.onSampledOutTrackPoint(trackPoint); } } } diff --git a/src/main/java/de/dennisguse/opentracks/content/TrackDataListener.java b/src/main/java/de/dennisguse/opentracks/content/TrackDataListener.java index a2c6de602..353be5a07 100644 --- a/src/main/java/de/dennisguse/opentracks/content/TrackDataListener.java +++ b/src/main/java/de/dennisguse/opentracks/content/TrackDataListener.java @@ -16,9 +16,8 @@ package de.dennisguse.opentracks.content; -import android.location.Location; - import de.dennisguse.opentracks.content.data.Track; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.Waypoint; /** @@ -43,20 +42,20 @@ public interface TrackDataListener { /** * Called when a sampled in track point is read. * - * @param location the location + * @param trackPoint the trackPoint */ - void onSampledInTrackPoint(Location location); + void onSampledInTrackPoint(TrackPoint trackPoint); /** * Called when a sampled out track point is read. * - * @param location the location + * @param trackPoint the trackPoint */ - void onSampledOutTrackPoint(Location location); + void onSampledOutTrackPoint(TrackPoint trackPoint); /** * Called when finish sending new track points. - * This gets called after every batch of calls to {@link #onSampledInTrackPoint(Location)} and {@link #onSampledOutTrackPoint(Location)}. + * This gets called after every batch of calls to {@link #onSampledInTrackPoint(TrackPoint)} and {@link #onSampledOutTrackPoint(TrackPoint)}. */ void onNewTrackPointsDone(); diff --git a/src/main/java/de/dennisguse/opentracks/content/data/Track.java b/src/main/java/de/dennisguse/opentracks/content/data/Track.java index 60660bacb..876ffd739 100644 --- a/src/main/java/de/dennisguse/opentracks/content/data/Track.java +++ b/src/main/java/de/dennisguse/opentracks/content/data/Track.java @@ -16,8 +16,6 @@ package de.dennisguse.opentracks.content.data; -import android.location.Location; - import androidx.annotation.VisibleForTesting; import java.util.ArrayList; @@ -43,7 +41,7 @@ public class Track { private TripStatistics tripStatistics = new TripStatistics(); // Location points (which may not have been loaded) - private List locations = new ArrayList<>(); + private List trackPoints = new ArrayList<>(); public Track() { } @@ -97,15 +95,15 @@ public class Track { } @VisibleForTesting - public void addLocation(Location location) { - locations.add(location); + public void addTrackPoint(TrackPoint location) { + trackPoints.add(location); } - public List getLocations() { - return locations; + public List getTrackPoints() { + return trackPoints; } - public void setLocations(ArrayList locations) { - this.locations = locations; + public void setTrackPoints(ArrayList trackPoints) { + this.trackPoints = trackPoints; } } diff --git a/src/main/java/de/dennisguse/opentracks/content/data/TrackPoint.java b/src/main/java/de/dennisguse/opentracks/content/data/TrackPoint.java index 33a045ad2..616e49410 100644 --- a/src/main/java/de/dennisguse/opentracks/content/data/TrackPoint.java +++ b/src/main/java/de/dennisguse/opentracks/content/data/TrackPoint.java @@ -16,6 +16,7 @@ package de.dennisguse.opentracks.content.data; import android.location.Location; +import android.location.LocationManager; import de.dennisguse.opentracks.content.sensor.SensorDataSet; @@ -24,8 +25,25 @@ import de.dennisguse.opentracks.content.sensor.SensorDataSet; * * @author Sandor Dornbush */ +//TODO Check if we can drop inheritance from Location and use attributes instead. public class TrackPoint extends Location { + public static TrackPoint createPause() { + TrackPoint pause = new TrackPoint(LocationManager.GPS_PROVIDER); + pause.setLongitude(0); + pause.setLatitude(TrackPointsColumns.PAUSE_LATITUDE); + pause.setTime(System.currentTimeMillis()); + return pause; + } + + public static TrackPoint createResume() { + TrackPoint resume = new TrackPoint(LocationManager.GPS_PROVIDER); + resume.setLongitude(0); + resume.setLatitude(TrackPointsColumns.RESUME_LATITUDE); + resume.setTime(System.currentTimeMillis()); + return resume; + } + private SensorDataSet sensorDataSet = null; public TrackPoint(Location location, SensorDataSet sensorDataSet) { 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 8f9b8a254..a59902632 100644 --- a/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java +++ b/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java @@ -622,34 +622,62 @@ public class ContentProviderUtils { } /** - * Inserts multiple track points. + * Fills a {@link TrackPoint} from a cursor. * - * @param locations an array of locations - * @param length the number of locations (from the beginning of the array) to - * insert, or -1 for all of them - * @param trackId the track id - * @return the number of points inserted + * @param cursor the cursor pointing to a trackPoint. + * @param indexes the cached track points indexes + * @param trackPoint the track point */ - public int bulkInsertTrackPoint(Location[] locations, int length, long trackId) { - if (length == -1) { - length = locations.length; + static void fillTrackPoint(Cursor cursor, CachedTrackPointsIndexes indexes, TrackPoint trackPoint) { + trackPoint.reset(); + + if (!cursor.isNull(indexes.longitudeIndex)) { + trackPoint.setLongitude(((double) cursor.getInt(indexes.longitudeIndex)) / 1E6); } - ContentValues[] values = new ContentValues[length]; - for (int i = 0; i < length; i++) { - values[i] = createContentValues(locations[i], trackId); + if (!cursor.isNull(indexes.latitudeIndex)) { + trackPoint.setLatitude(((double) cursor.getInt(indexes.latitudeIndex)) / 1E6); } - return contentResolver.bulkInsert(TrackPointsColumns.CONTENT_URI_BY_ID, values); + if (!cursor.isNull(indexes.timeIndex)) { + trackPoint.setTime(cursor.getLong(indexes.timeIndex)); + } + if (!cursor.isNull(indexes.altitudeIndex)) { + trackPoint.setAltitude(cursor.getFloat(indexes.altitudeIndex)); + } + if (!cursor.isNull(indexes.accuracyIndex)) { + trackPoint.setAccuracy(cursor.getFloat(indexes.accuracyIndex)); + } + if (!cursor.isNull(indexes.speedIndex)) { + trackPoint.setSpeed(cursor.getFloat(indexes.speedIndex)); + } + if (!cursor.isNull(indexes.bearingIndex)) { + trackPoint.setBearing(cursor.getFloat(indexes.bearingIndex)); + } + + float heartRate = cursor.isNull(indexes.sensorHeartRateIndex) ? SensorDataSet.DATA_UNAVAILABLE : cursor.getFloat(indexes.sensorHeartRateIndex); + float cadence = cursor.isNull(indexes.sensorCadenceIndex) ? SensorDataSet.DATA_UNAVAILABLE : cursor.getFloat(indexes.sensorCadenceIndex); + float power = cursor.isNull(indexes.sensorPowerIndex) ? SensorDataSet.DATA_UNAVAILABLE : cursor.getFloat(indexes.sensorPowerIndex); + + trackPoint.setSensorDataSet(new SensorDataSet(heartRate, cadence, power, SensorDataSet.DATA_UNAVAILABLE, trackPoint.getTime())); } /** - * Creates a location object from a cursor. + * Inserts multiple trackPoints points. * - * @param cursor the cursor pointing to the location + * @param trackPoints an array of trackPoints + * @param length the number of trackPoints (from the beginning of the array) to + * insert, or -1 for all of them + * @param trackId the trackPoints id + * @return the number of points inserted */ - public Location createTrackPoint(Cursor cursor) { - Location location = new TrackPoint(""); - fillTrackPoint(cursor, new CachedTrackPointsIndexes(cursor), location); - return location; + public int bulkInsertTrackPoint(TrackPoint[] trackPoints, int length, long trackId) { + if (length == -1) { + length = trackPoints.length; + } + ContentValues[] values = new ContentValues[length]; + for (int i = 0; i < length; i++) { + values[i] = createContentValues(trackPoints[i], trackId); + } + return contentResolver.bulkInsert(TrackPointsColumns.CONTENT_URI_BY_ID, values); } /** @@ -722,21 +750,14 @@ public class ContentProviderUtils { } /** - * Gets the last valid location for a track. - * Returns null if it doesn't exist. + * Creates a location object from a cursor. * - * @param trackId the track id + * @param cursor the cursor pointing to the location */ - @Deprecated - public Location getLastValidTrackPoint(long trackId) { - if (trackId < 0) { - return null; - } - String selection = TrackPointsColumns._ID + "=(select max(" + TrackPointsColumns._ID + ") from " - + TrackPointsColumns.TABLE_NAME + " WHERE " + TrackPointsColumns.TRACKID + "=? AND " - + TrackPointsColumns.LATITUDE + "<=" + MAX_LATITUDE + ")"; - String[] selectionArgs = new String[]{Long.toString(trackId)}; - return findTrackPointBy(selection, selectionArgs); + public TrackPoint createTrackPoint(Cursor cursor) { + TrackPoint location = new TrackPoint(""); + fillTrackPoint(cursor, new CachedTrackPointsIndexes(cursor), location); + return location; } /** @@ -774,99 +795,71 @@ public class ContentProviderUtils { return getTrackPointCursor(null, selection, selectionArgs, sortOrder); } - /** - * Fills a track point from a cursor. + * Gets the last valid location for a track. + * Returns null if it doesn't exist. * - * @param cursor the cursor pointing to a location. - * @param indexes the cached track points indexes - * @param location the track point + * @param trackId the track id */ - static void fillTrackPoint(Cursor cursor, CachedTrackPointsIndexes indexes, Location location) { - location.reset(); - - if (!cursor.isNull(indexes.longitudeIndex)) { - location.setLongitude(((double) cursor.getInt(indexes.longitudeIndex)) / 1E6); - } - if (!cursor.isNull(indexes.latitudeIndex)) { - location.setLatitude(((double) cursor.getInt(indexes.latitudeIndex)) / 1E6); - } - if (!cursor.isNull(indexes.timeIndex)) { - location.setTime(cursor.getLong(indexes.timeIndex)); - } - if (!cursor.isNull(indexes.altitudeIndex)) { - location.setAltitude(cursor.getFloat(indexes.altitudeIndex)); - } - if (!cursor.isNull(indexes.accuracyIndex)) { - location.setAccuracy(cursor.getFloat(indexes.accuracyIndex)); - } - if (!cursor.isNull(indexes.speedIndex)) { - location.setSpeed(cursor.getFloat(indexes.speedIndex)); - } - if (!cursor.isNull(indexes.bearingIndex)) { - location.setBearing(cursor.getFloat(indexes.bearingIndex)); - } - if (location instanceof TrackPoint) { - TrackPoint sensorDataSetLocation = (TrackPoint) location; - - float heartRate = cursor.isNull(indexes.sensorHeartRateIndex) ? SensorDataSet.DATA_UNAVAILABLE : cursor.getFloat(indexes.sensorHeartRateIndex); - float cadence = cursor.isNull(indexes.sensorCadenceIndex) ? SensorDataSet.DATA_UNAVAILABLE : cursor.getFloat(indexes.sensorCadenceIndex); - float power = cursor.isNull(indexes.sensorPowerIndex) ? SensorDataSet.DATA_UNAVAILABLE : cursor.getFloat(indexes.sensorPowerIndex); - - sensorDataSetLocation.setSensorDataSet(new SensorDataSet(heartRate, cadence, power, SensorDataSet.DATA_UNAVAILABLE, location.getTime())); + @Deprecated + public TrackPoint getLastValidTrackPoint(long trackId) { + if (trackId < 0) { + return null; } + String selection = TrackPointsColumns._ID + "=(select max(" + TrackPointsColumns._ID + ") from " + + TrackPointsColumns.TABLE_NAME + " WHERE " + TrackPointsColumns.TRACKID + "=? AND " + + TrackPointsColumns.LATITUDE + "<=" + MAX_LATITUDE + ")"; + String[] selectionArgs = new String[]{Long.toString(trackId)}; + return findTrackPointBy(selection, selectionArgs); } /** * Inserts a track point. * - * @param location the location + * @param trackPoint the trackPoint * @param trackId the track id * @return the content provider URI of the inserted track point */ - public Uri insertTrackPoint(Location location, long trackId) { - return contentResolver.insert(TrackPointsColumns.CONTENT_URI_BY_ID, createContentValues(location, trackId)); + public Uri insertTrackPoint(TrackPoint trackPoint, long trackId) { + return contentResolver.insert(TrackPointsColumns.CONTENT_URI_BY_ID, createContentValues(trackPoint, trackId)); } /** - * Creates the {@link ContentValues} for a {@link Location}. + * Creates the {@link ContentValues} for a {@link TrackPoint}. * - * @param location the location + * @param trackPoint the trackPoint * @param trackId the track id */ - private ContentValues createContentValues(Location location, long trackId) { + private ContentValues createContentValues(TrackPoint trackPoint, long trackId) { ContentValues values = new ContentValues(); values.put(TrackPointsColumns.TRACKID, trackId); - values.put(TrackPointsColumns.LONGITUDE, (int) (location.getLongitude() * 1E6)); - values.put(TrackPointsColumns.LATITUDE, (int) (location.getLatitude() * 1E6)); + values.put(TrackPointsColumns.LONGITUDE, (int) (trackPoint.getLongitude() * 1E6)); + values.put(TrackPointsColumns.LATITUDE, (int) (trackPoint.getLatitude() * 1E6)); - values.put(TrackPointsColumns.TIME, location.getTime()); - if (location.hasAltitude()) { - values.put(TrackPointsColumns.ALTITUDE, location.getAltitude()); + values.put(TrackPointsColumns.TIME, trackPoint.getTime()); + if (trackPoint.hasAltitude()) { + values.put(TrackPointsColumns.ALTITUDE, trackPoint.getAltitude()); } - if (location.hasAccuracy()) { - values.put(TrackPointsColumns.ACCURACY, location.getAccuracy()); + if (trackPoint.hasAccuracy()) { + values.put(TrackPointsColumns.ACCURACY, trackPoint.getAccuracy()); } - if (location.hasSpeed()) { - values.put(TrackPointsColumns.SPEED, location.getSpeed()); + if (trackPoint.hasSpeed()) { + values.put(TrackPointsColumns.SPEED, trackPoint.getSpeed()); } - if (location.hasBearing()) { - values.put(TrackPointsColumns.BEARING, location.getBearing()); + if (trackPoint.hasBearing()) { + values.put(TrackPointsColumns.BEARING, trackPoint.getBearing()); } //SensorData - if (location instanceof TrackPoint) { - TrackPoint sensorDataSetLocation = (TrackPoint) location; - SensorDataSet sensorDataSet = sensorDataSetLocation.getSensorDataSet(); - if (sensorDataSet != null && sensorDataSet.hasHeartRate()) { - values.put(TrackPointsColumns.SENSOR_HEARTRATE, sensorDataSetLocation.getSensorDataSet().getHeartRate()); - } - if (sensorDataSet != null && sensorDataSet.hasCadence()) { - values.put(TrackPointsColumns.SENSOR_CADENCE, sensorDataSetLocation.getSensorDataSet().getCadence()); - } - if (sensorDataSet != null && sensorDataSet.hasPower()) { - values.put(TrackPointsColumns.SENSOR_POWER, sensorDataSetLocation.getSensorDataSet().getPower()); - } + SensorDataSet sensorDataSet = trackPoint.getSensorDataSet(); + if (sensorDataSet != null && sensorDataSet.hasHeartRate()) { + values.put(TrackPointsColumns.SENSOR_HEARTRATE, trackPoint.getSensorDataSet().getHeartRate()); + } + if (sensorDataSet != null && sensorDataSet.hasCadence()) { + values.put(TrackPointsColumns.SENSOR_CADENCE, trackPoint.getSensorDataSet().getCadence()); + } + if (sensorDataSet != null && sensorDataSet.hasPower()) { + values.put(TrackPointsColumns.SENSOR_POWER, trackPoint.getSensorDataSet().getPower()); } return values; } @@ -875,7 +868,7 @@ public class ContentProviderUtils { * Creates a new read-only iterator over a given track's points. * It provides a lightweight way of iterating over long tracks without failing due to the underlying cursor limitations. * Since it's a read-only iterator, {@link Iterator#remove()} always throws {@link UnsupportedOperationException}. - * Each call to {@link TrackPointIterator#next()} may advance to the next DB record, and if so, the iterator calls {@link TrackPointFactory#createLocation()} and populates it with information retrieved from the record. + * Each call to {@link TrackPointIterator#next()} may advance to the next DB record, and if so, the iterator calls {@link TrackPointFactory#create()} and populates it with information retrieved from the record. * When done with iteration, {@link TrackPointIterator#close()} must be called. * * @param trackId the track id @@ -887,7 +880,7 @@ public class ContentProviderUtils { return new TrackPointIterator(this, trackId, startTrackPointId, descending, trackPointFactory); } - private Location findTrackPointBy(String selection, String[] selectionArgs) { + private TrackPoint findTrackPointBy(String selection, String[] selectionArgs) { try (Cursor cursor = getTrackPointCursor(null, selection, selectionArgs, TrackPointsColumns._ID)) { if (cursor != null && cursor.moveToNext()) { return createTrackPoint(cursor); diff --git a/src/main/java/de/dennisguse/opentracks/content/provider/TrackPointFactory.java b/src/main/java/de/dennisguse/opentracks/content/provider/TrackPointFactory.java index 19ad1ff6b..ceb0fe90a 100644 --- a/src/main/java/de/dennisguse/opentracks/content/provider/TrackPointFactory.java +++ b/src/main/java/de/dennisguse/opentracks/content/provider/TrackPointFactory.java @@ -15,7 +15,7 @@ public class TrackPointFactory { */ public static final TrackPointFactory DEFAULT_LOCATION_FACTORY = new TrackPointFactory(); - public TrackPoint createLocation() { + public TrackPoint create() { return new TrackPoint(LocationManager.GPS_PROVIDER); } } 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 309527560..711e90cb9 100644 --- a/src/main/java/de/dennisguse/opentracks/content/provider/TrackPointIterator.java +++ b/src/main/java/de/dennisguse/opentracks/content/provider/TrackPointIterator.java @@ -91,7 +91,7 @@ public class TrackPointIterator implements Iterator, AutoCloseable { } } lastTrackPointId = cursor.getLong(indexes.idIndex); - TrackPoint trackPoint = trackPointFactory.createLocation(); + TrackPoint trackPoint = trackPointFactory.create(); ContentProviderUtils.fillTrackPoint(cursor, indexes, trackPoint); return trackPoint; } diff --git a/src/main/java/de/dennisguse/opentracks/fragments/ChartFragment.java b/src/main/java/de/dennisguse/opentracks/fragments/ChartFragment.java index f742209aa..e44b18cf2 100644 --- a/src/main/java/de/dennisguse/opentracks/fragments/ChartFragment.java +++ b/src/main/java/de/dennisguse/opentracks/fragments/ChartFragment.java @@ -17,7 +17,6 @@ package de.dennisguse.opentracks.fragments; import android.content.SharedPreferences; -import android.location.Location; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -220,18 +219,18 @@ public class ChartFragment extends Fragment implements TrackDataListener { } @Override - public void onSampledInTrackPoint(Location location) { + public void onSampledInTrackPoint(TrackPoint trackPoint) { if (isResumed()) { double[] data = new double[ChartView.NUM_SERIES + 1]; - fillDataPoint(location, data); + fillDataPoint(trackPoint, data); pendingPoints.add(data); } } @Override - public void onSampledOutTrackPoint(Location location) { + public void onSampledOutTrackPoint(TrackPoint trackPoint) { if (isResumed()) { - fillDataPoint(location, null); + fillDataPoint(trackPoint, null); } } @@ -351,7 +350,7 @@ public class ChartFragment extends Fragment implements TrackDataListener { } /** - * Given a location, fill in a data point, an array of double[].
+ * Given a trackPoint, fill in a data point, an array of double[].
* data[0] = time/distance
* data[1] = elevation
* data[2] = speed
@@ -360,18 +359,18 @@ public class ChartFragment extends Fragment implements TrackDataListener { * data[5] = cadence
* data[6] = power
* - * @param location the location + * @param trackPoint the trackPoint * @param data the data point to fill in, can be null */ @VisibleForTesting - void fillDataPoint(Location location, double[] data) { + void fillDataPoint(@NonNull TrackPoint trackPoint, double[] data) { double timeOrDistance = Double.NaN; double elevation = Double.NaN; double speed = Double.NaN; double pace = Double.NaN; if (tripStatisticsUpdater != null) { - tripStatisticsUpdater.addLocation(location, recordingDistanceInterval); + tripStatisticsUpdater.addTrackPoint(trackPoint, recordingDistanceInterval); TripStatistics tripStatistics = tripStatisticsUpdater.getTripStatistics(); if (chartByDistance) { double distance = tripStatistics.getTotalDistance() * UnitConversions.M_TO_KM; @@ -398,8 +397,8 @@ public class ChartFragment extends Fragment implements TrackDataListener { double heartRate = Double.NaN; double cadence = Double.NaN; double power = Double.NaN; - if (location instanceof TrackPoint && ((TrackPoint) location).getSensorDataSet() != null) { - SensorDataSet sensorDataSet = ((TrackPoint) location).getSensorDataSet(); + if (trackPoint.getSensorDataSet() != null) { + SensorDataSet sensorDataSet = trackPoint.getSensorDataSet(); if (sensorDataSet.hasHeartRate()) { heartRate = sensorDataSet.getHeartRate(); } diff --git a/src/main/java/de/dennisguse/opentracks/fragments/StatsFragment.java b/src/main/java/de/dennisguse/opentracks/fragments/StatsFragment.java index 963997968..cabfbf6f9 100644 --- a/src/main/java/de/dennisguse/opentracks/fragments/StatsFragment.java +++ b/src/main/java/de/dennisguse/opentracks/fragments/StatsFragment.java @@ -17,7 +17,6 @@ package de.dennisguse.opentracks.fragments; import android.content.SharedPreferences; -import android.location.Location; import android.os.Bundle; import android.os.Handler; import android.util.Log; @@ -42,6 +41,7 @@ import de.dennisguse.opentracks.content.TrackDataHub; import de.dennisguse.opentracks.content.TrackDataListener; import de.dennisguse.opentracks.content.TrackDataType; import de.dennisguse.opentracks.content.data.Track; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.Waypoint; import de.dennisguse.opentracks.content.sensor.SensorDataSet; import de.dennisguse.opentracks.services.TrackRecordingServiceConnection; @@ -72,7 +72,7 @@ public class StatsFragment extends Fragment implements TrackDataListener { //TODO Initialize immediately and remove in onDestroy() private TrackRecordingServiceConnection trackRecordingServiceConnection; - private Location lastLocation = null; + private TrackPoint lastTrackPoint = null; private TripStatistics lastTripStatistics = null; private String category = ""; @@ -333,17 +333,17 @@ public class StatsFragment extends Fragment implements TrackDataListener { @Override public void clearTrackPoints() { - lastLocation = null; + lastTrackPoint = null; } @Override - public void onSampledInTrackPoint(Location location) { - lastLocation = location; + public void onSampledInTrackPoint(TrackPoint trackPoint) { + lastTrackPoint = trackPoint; } @Override - public void onSampledOutTrackPoint(Location location) { - lastLocation = location; + public void onSampledOutTrackPoint(TrackPoint trackPoint) { + lastTrackPoint = trackPoint; } @Override @@ -354,15 +354,15 @@ public class StatsFragment extends Fragment implements TrackDataListener { public void run() { if (isResumed()) { if (!isSelectedTrackRecording() || isSelectedTrackPaused()) { - lastLocation = null; + lastTrackPoint = null; } - if (lastLocation != null) { - boolean hasFix = !LocationUtils.isLocationOld(lastLocation); - boolean hasGoodFix = lastLocation.hasAccuracy() && lastLocation.getAccuracy() < recordingGpsAccuracy; + if (lastTrackPoint != null) { + boolean hasFix = !LocationUtils.isLocationOld(lastTrackPoint); + boolean hasGoodFix = lastTrackPoint.hasAccuracy() && lastTrackPoint.getAccuracy() < recordingGpsAccuracy; if (!hasFix || !hasGoodFix) { - lastLocation = null; + lastTrackPoint = null; } } setLocationValues(); @@ -573,7 +573,7 @@ public class StatsFragment extends Fragment implements TrackDataListener { if (isRecording) { speedLabel.setText(reportSpeed ? R.string.stats_speed : R.string.stats_pace); - double speed = lastLocation != null && lastLocation.hasSpeed() ? lastLocation.getSpeed() : Double.NaN; + double speed = lastTrackPoint != null && lastTrackPoint.hasSpeed() ? lastTrackPoint.getSpeed() : Double.NaN; Pair parts = StringUtils.getSpeedParts(getContext(), speed, metricUnits, reportSpeed); speedValue.setText(parts.first); speedUnit.setText(parts.second); @@ -584,7 +584,7 @@ public class StatsFragment extends Fragment implements TrackDataListener { gradeElevationContainer.setVisibility(showGradeElevation ? View.VISIBLE : View.GONE); if (showGradeElevation) { - double altitude = lastLocation != null && lastLocation.hasAltitude() ? lastLocation.getAltitude() : Double.NaN; + double altitude = lastTrackPoint != null && lastTrackPoint.hasAltitude() ? lastTrackPoint.getAltitude() : Double.NaN; Pair parts = StringUtils.formatElevation(getContext(), altitude, metricUnits); elevationValue.setText(parts.first); @@ -597,11 +597,11 @@ public class StatsFragment extends Fragment implements TrackDataListener { coordinateSeparator.setVisibility(showCoordinate ? View.VISIBLE : View.GONE); coordinateContainer.setVisibility(showCoordinate ? View.VISIBLE : View.GONE); if (showCoordinate) { - double latitude = lastLocation != null ? lastLocation.getLatitude() : Double.NaN; + double latitude = lastTrackPoint != null ? lastTrackPoint.getLatitude() : Double.NaN; String latitudeText = Double.isNaN(latitude) || Double.isInfinite(latitude) ? getContext().getString(R.string.value_unknown) : StringUtils.formatCoordinate(latitude); latitudeValue.setText(latitudeText); - double longitude = lastLocation != null ? lastLocation.getLongitude() : Double.NaN; + double longitude = lastTrackPoint != null ? lastTrackPoint.getLongitude() : Double.NaN; String longitudeText = Double.isNaN(longitude) || Double.isInfinite(longitude) ? getContext().getString(R.string.value_unknown) : StringUtils.formatCoordinate(longitude); longitudeValue.setText(longitudeText); } 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 d9516e2ee..1027fc0f4 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 @@ -18,7 +18,6 @@ package de.dennisguse.opentracks.io.file.exporter; import android.content.Context; import android.database.Cursor; -import android.location.Location; import android.util.Log; import androidx.annotation.NonNull; @@ -129,22 +128,22 @@ public class FileTrackExporter implements TrackExporter { TrackWriterTrackPointFactory trackPointFactory = new TrackWriterTrackPointFactory(); int locationNumber = 0; - try (TrackPointIterator locationIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L, false, trackPointFactory)) { + try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L, false, trackPointFactory)) { - while (locationIterator.hasNext()) { + while (trackPointIterator.hasNext()) { if (Thread.interrupted()) { throw new InterruptedException(); } - Location location = locationIterator.next(); + TrackPoint trackPoint = trackPointIterator.next(); - setLocationTime(location, offset); + setLocationTime(trackPoint, offset); locationNumber++; - boolean isLocationValid = LocationUtils.isValidLocation(location); + boolean isLocationValid = LocationUtils.isValidLocation(trackPoint); boolean isSegmentValid = isLocationValid && isLastLocationValid; if (!wroteTrack && isSegmentValid) { // Found the first two consecutive locations that are valid - trackWriter.writeBeginTrack(track, trackPointFactory.lastLocation); + trackWriter.writeBeginTrack(track, trackPointFactory.lastTrackPoint); wroteTrack = true; } @@ -154,14 +153,14 @@ public class FileTrackExporter implements TrackExporter { trackWriter.writeOpenSegment(); wroteSegment = true; - // Write the previous location, which we had previously skipped - trackWriter.writeLocation(trackPointFactory.lastLocation); + // Write the previous trackPoint, which we had previously skipped + trackWriter.writeTrackPoint(trackPointFactory.lastTrackPoint); } - // Write the current location - trackWriter.writeLocation(location); + // Write the current trackPoint + trackWriter.writeTrackPoint(trackPoint); if (trackExporterListener != null) { - trackExporterListener.onProgressUpdate(locationNumber, locationIterator.getCount()); + trackExporterListener.onProgressUpdate(locationNumber, trackPointIterator.getCount()); } } else { if (wroteSegment) { @@ -179,7 +178,7 @@ public class FileTrackExporter implements TrackExporter { } if (wroteTrack) { - Location lastValidTrackPoint = contentProviderUtils.getLastValidTrackPoint(track.getId()); + TrackPoint lastValidTrackPoint = contentProviderUtils.getLastValidTrackPoint(track.getId()); setLocationTime(lastValidTrackPoint, offset); trackWriter.writeEndTrack(track, lastValidTrackPoint); } else { @@ -191,40 +190,40 @@ public class FileTrackExporter implements TrackExporter { } /** - * Sets a location time. + * Sets a trackPoint time. * - * @param location the location + * @param trackPoint the trackPoint * @param offset the time offset */ - private void setLocationTime(Location location, long offset) { - if (location != null) { - location.setTime(location.getTime() - offset); + private void setLocationTime(TrackPoint trackPoint, long offset) { + if (trackPoint != null) { + trackPoint.setTime(trackPoint.getTime() - offset); } } /** - * Track writer location factory. Keeping the last two locations. + * Keeping the last two locations. * * @author Jimmy Shih */ private class TrackWriterTrackPointFactory extends TrackPointFactory { - TrackPoint currentLocation; - TrackPoint lastLocation; + TrackPoint currentTrackPoint; + TrackPoint lastTrackPoint; @Override - public TrackPoint createLocation() { - if (currentLocation == null) { - currentLocation = new TrackPoint(""); + public TrackPoint create() { + if (currentTrackPoint == null) { + currentTrackPoint = new TrackPoint(""); } - return currentLocation; + return currentTrackPoint; } void swapLocations() { - TrackPoint tempLocation = lastLocation; - lastLocation = currentLocation; - currentLocation = tempLocation; - if (currentLocation != null) { - currentLocation.reset(); + TrackPoint tempTrackPoint = lastTrackPoint; + lastTrackPoint = currentTrackPoint; + currentTrackPoint = tempTrackPoint; + if (currentTrackPoint != null) { + currentTrackPoint.reset(); } } } diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GpxTrackWriter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GpxTrackWriter.java index 2f5cb6409..d4f6503ba 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GpxTrackWriter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GpxTrackWriter.java @@ -24,6 +24,7 @@ import java.text.NumberFormat; import java.util.Locale; import de.dennisguse.opentracks.content.data.Track; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.Waypoint; import de.dennisguse.opentracks.util.StringUtils; @@ -139,7 +140,7 @@ public class GpxTrackWriter implements TrackWriter { } @Override - public void writeBeginTrack(Track track, Location startLocation) { + public void writeBeginTrack(Track track, TrackPoint startTrackPoint) { if (printWriter != null) { printWriter.println(""); printWriter.println("" + StringUtils.formatCData(track.getName()) + ""); @@ -150,7 +151,7 @@ public class GpxTrackWriter implements TrackWriter { } @Override - public void writeEndTrack(Track track, Location endLocation) { + public void writeEndTrack(Track track, TrackPoint endTrackPoint) { if (printWriter != null) { printWriter.println(""); } @@ -167,14 +168,14 @@ public class GpxTrackWriter implements TrackWriter { } @Override - public void writeLocation(Location location) { + public void writeTrackPoint(TrackPoint trackPoint) { if (printWriter != null) { - printWriter.println(""); - if (location.hasAltitude()) { - printWriter.println("" + ELEVATION_FORMAT.format(location.getAltitude()) + ""); + printWriter.println(""); + if (trackPoint.hasAltitude()) { + printWriter.println("" + ELEVATION_FORMAT.format(trackPoint.getAltitude()) + ""); } printWriter.println( - ""); + ""); printWriter.println(""); } } 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 be3ba1fa2..13e66e151 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 @@ -69,7 +69,7 @@ public class KmlTrackWriter implements TrackWriter { private final List cadenceList = new ArrayList<>(); private final List heartRateList = new ArrayList<>(); - private Location startLocation; + private TrackPoint startTrackPoint; /** * @param context the context @@ -188,11 +188,11 @@ public class KmlTrackWriter implements TrackWriter { } @Override - public void writeBeginTrack(Track track, Location startLocation) { - this.startLocation = startLocation; + public void writeBeginTrack(Track track, TrackPoint startTrackPoint) { + this.startTrackPoint = startTrackPoint; if (printWriter != null) { String name = context.getString(R.string.marker_label_start, track.getName()); - writePlacemark(name, "", "", START_STYLE, startLocation); + writePlacemark(name, "", "", START_STYLE, startTrackPoint); printWriter.println(""); if (exportTrackDetail) { @@ -210,7 +210,7 @@ public class KmlTrackWriter implements TrackWriter { } @Override - public void writeEndTrack(Track track, Location endLocation) { + public void writeEndTrack(Track track, TrackPoint endTrackPoint) { if (printWriter != null) { printWriter.println(""); printWriter.println(""); @@ -218,7 +218,7 @@ public class KmlTrackWriter implements TrackWriter { if (exportTrackDetail) { String name = context.getString(R.string.marker_label_end, track.getName()); String description = descriptionGenerator.generateTrackDescription(track, false); - writePlacemark(name, "", description, END_STYLE, endLocation); + writePlacemark(name, "", description, END_STYLE, endTrackPoint); } } } @@ -256,16 +256,16 @@ public class KmlTrackWriter implements TrackWriter { } @Override - public void writeLocation(Location location) { + public void writeTrackPoint(TrackPoint trackPoint) { if (printWriter != null) { if (exportTrackDetail) { - printWriter.println("" + getTime(location) + ""); + printWriter.println("" + getTime(trackPoint) + ""); } - printWriter.println("" + getCoordinates(location, " ") + ""); + printWriter.println("" + getCoordinates(trackPoint, " ") + ""); - if (exportSensorData && location instanceof TrackPoint) { - SensorDataSet sensorDataSet = ((TrackPoint) location).getSensorDataSet(); + if (exportSensorData) { + SensorDataSet sensorDataSet = trackPoint.getSensorDataSet(); if (sensorDataSet != null) { if (sensorDataSet.hasHeartRate()) { heartRateList.add(sensorDataSet.getHeartRate()); @@ -371,7 +371,7 @@ public class KmlTrackWriter implements TrackWriter { if (exportTrackDetail) { return StringUtils.formatDateTimeIso8601(location.getTime()); } else { - return StringUtils.formatDateTimeIso8601(location.getTime() - startLocation.getTime()); + return StringUtils.formatDateTimeIso8601(location.getTime() - startTrackPoint.getTime()); } } diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/TrackExporterListener.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/TrackExporterListener.java index 01b728297..e7893c1d2 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/TrackExporterListener.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/TrackExporterListener.java @@ -25,8 +25,8 @@ public interface TrackExporterListener { /** * Called to update progress. * - * @param number the number of locations written - * @param max the maximum number of locations in a track, for calculation of + * @param number the number of {@link de.dennisguse.opentracks.content.data.TrackPoint}s written + * @param max the maximum number of {@link de.dennisguse.opentracks.content.data.TrackPoint}s in a {@link de.dennisguse.opentracks.content.data.Track}, for calculation of * completion percentage */ void onProgressUpdate(int number, int max); diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/TrackWriter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/TrackWriter.java index 616e2dff2..27ef89179 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/TrackWriter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/TrackWriter.java @@ -15,11 +15,10 @@ */ package de.dennisguse.opentracks.io.file.exporter; -import android.location.Location; - import java.io.OutputStream; import de.dennisguse.opentracks.content.data.Track; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.Waypoint; /** @@ -35,13 +34,13 @@ import de.dennisguse.opentracks.content.data.Waypoint; * {@link #writeEndWaypoints()} * {@link #writeBeginTracks()} * For each track: - * {@link #writeBeginTrack(Track, Location)} + * {@link #writeBeginTrack(Track, TrackPoint)} * For each segment: * {@link #writeOpenSegment()} - * For each location in the segment: - * {@link #writeLocation(Location)} + * For each trackPoint in the segment: + * {@link #writeTrackPoint(TrackPoint)} * {@link #writeCloseSegment()} - * {@link #writeEndTrack(Track, Location)} + * {@link #writeEndTrack(Track, TrackPoint)} * {@link #writeEndTracks()} * {@link #writeFooter()} * {@link #close()} @@ -107,18 +106,18 @@ public interface TrackWriter { /** * Writes the beginning of a track. * - * @param track the track - * @param startLocation the start location + * @param track the track + * @param startTrackPoint the start location */ - void writeBeginTrack(Track track, Location startLocation); + void writeBeginTrack(Track track, TrackPoint startTrackPoint); /** * Writes the end of a track. * - * @param track the track - * @param endLocation the end location + * @param track the track + * @param endTrackPoint the end location */ - void writeEndTrack(Track track, Location endLocation); + void writeEndTrack(Track track, TrackPoint endTrackPoint); /** * Writes open segment. @@ -131,9 +130,9 @@ public interface TrackWriter { void writeCloseSegment(); /** - * Writes a location. + * Writes a trackPoint. * - * @param location the location + * @param trackPoint the trackPoint */ - void writeLocation(Location location); + void writeTrackPoint(TrackPoint trackPoint); } \ No newline at end of file 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 ac367c075..118676a3e 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 @@ -39,6 +39,7 @@ import javax.xml.parsers.SAXParserFactory; import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.content.data.Track; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.TrackPointsColumns; import de.dennisguse.opentracks.content.data.Waypoint; import de.dennisguse.opentracks.content.provider.ContentProviderUtils; @@ -158,12 +159,12 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track int waypointPosition = -1; Waypoint waypoint = null; - Location location = null; + TrackPoint trackPoint = null; TripStatisticsUpdater trackTripStatisticstrackUpdater = new TripStatisticsUpdater(track.getTripStatistics().getStartTime()); @Deprecated // TODO Should not be necessary anymore? TripStatisticsUpdater markerTripStatisticsUpdater = new TripStatisticsUpdater(track.getTripStatistics().getStartTime()); - try (TrackPointIterator locationIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L, false, TrackPointFactory.DEFAULT_LOCATION_FACTORY)) { + try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L, false, TrackPointFactory.DEFAULT_LOCATION_FACTORY)) { while (true) { if (waypoint == null) { @@ -175,38 +176,38 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track } } - if (location == null) { - if (!locationIterator.hasNext()) { + if (trackPoint == null) { + if (!trackPointIterator.hasNext()) { // No more track points. Ignore the rest of the waypoints. return; } - location = locationIterator.next(); - trackTripStatisticstrackUpdater.addLocation(location, recordingDistanceInterval); - markerTripStatisticsUpdater.addLocation(location, recordingDistanceInterval); + trackPoint = trackPointIterator.next(); + trackTripStatisticstrackUpdater.addTrackPoint(trackPoint, recordingDistanceInterval); + markerTripStatisticsUpdater.addTrackPoint(trackPoint, recordingDistanceInterval); } - if (waypoint.getLocation().getTime() > location.getTime()) { - location = null; - } else if (waypoint.getLocation().getTime() < location.getTime()) { - Log.w(TAG, "Ignoring waypoint: current location was after waypoint."); + if (waypoint.getLocation().getTime() > trackPoint.getTime()) { + trackPoint = null; + } else if (waypoint.getLocation().getTime() < trackPoint.getTime()) { + Log.w(TAG, "Ignoring waypoint: current trackPoint was after waypoint."); waypoint = null; } else { - // The waypoint location time matches the track point time - if (!LocationUtils.isValidLocation(location)) { - // Invalid location, load the next location - location = null; + // The waypoint trackPoint time matches the track point time + if (!LocationUtils.isValidLocation(trackPoint)) { + // Invalid trackPoint, load the next trackPoint + trackPoint = null; continue; } - // Valid location - if (location.getLatitude() == waypoint.getLocation().getLatitude() && location.getLongitude() == waypoint.getLocation().getLongitude()) { + // Valid trackPoint + if (trackPoint.getLatitude() == waypoint.getLocation().getLatitude() && trackPoint.getLongitude() == waypoint.getLocation().getLongitude()) { String waypointDescription = waypoint.getDescription(); String icon = context.getString(R.string.marker_waypoint_icon_url); double length = trackTripStatisticstrackUpdater.getTripStatistics().getTotalDistance(); long duration = trackTripStatisticstrackUpdater.getTripStatistics().getTotalTime(); // Insert waypoint - Waypoint newWaypoint = new Waypoint(waypoint.getName(), waypointDescription, waypoint.getCategory(), icon, track.getId(), length, duration, location, waypoint.getPhotoUrl()); + Waypoint newWaypoint = new Waypoint(waypoint.getName(), waypointDescription, waypoint.getCategory(), icon, track.getId(), length, duration, trackPoint, waypoint.getPhotoUrl()); contentProviderUtils.insertWaypoint(newWaypoint); } @@ -273,7 +274,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track //If not the first segment, add a pause separator if there is at least one location in the last segment. if (trackData.numberOfSegments > 1 && trackData.lastLocationInCurrentSegment != null) { - insertLocation(createLocation(TrackPointsColumns.PAUSE_LATITUDE, 0.0, 0.0, trackData.lastLocationInCurrentSegment.getTime())); + insertLocation(createTrackPoint(TrackPointsColumns.PAUSE_LATITUDE, 0.0, 0.0, trackData.lastLocationInCurrentSegment.getTime())); } trackData.lastLocationInCurrentSegment = null; } @@ -288,7 +289,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track } Waypoint waypoint = new Waypoint(); - Location location = createLocation(); + TrackPoint location = createTrackPoint(); if (!LocationUtils.isValidLocation(location)) { throw new SAXException(createErrorMessage("Invalid location detected: " + location)); @@ -314,8 +315,8 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track /** * Gets a track point. */ - protected Location getTrackPoint() throws SAXException { - Location location = createLocation(); + protected TrackPoint getTrackPoint() throws SAXException { + TrackPoint location = createTrackPoint(); // Calculate derived attributes from the previous point if (trackData.lastLocationInCurrentSegment != null && trackData.lastLocationInCurrentSegment.getTime() != 0) { @@ -343,7 +344,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track if (trackData.numberOfSegments > 1 && trackData.lastLocationInCurrentSegment == null) { // If not the first segment, add a resume separator before adding the first location. - insertLocation(createLocation(TrackPointsColumns.RESUME_LATITUDE, 0.0, 0.0, location.getTime())); + insertLocation(createTrackPoint(TrackPointsColumns.RESUME_LATITUDE, 0.0, 0.0, location.getTime())); } trackData.lastLocationInCurrentSegment = location; return location; @@ -352,10 +353,10 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track /** * Inserts a track point. * - * @param location the location + * @param trackPoint the trackPoint */ - protected void insertTrackPoint(Location location) { - insertLocation(location); + protected void insertTrackPoint(TrackPoint trackPoint) { + insertLocation(trackPoint); } /** @@ -384,7 +385,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track /** * Creates a location. */ - private Location createLocation() throws SAXException { + private TrackPoint createTrackPoint() throws SAXException { if (latitude == null || longitude == null) { return null; } @@ -415,7 +416,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track throw new SAXException(createErrorMessage(String.format(Locale.US, "Unable to parse time: %s", time)), e); } } - return createLocation(latitudeValue, longitudeValue, altitudeValue, timeValue); + return createTrackPoint(latitudeValue, longitudeValue, altitudeValue, timeValue); } /** @@ -426,8 +427,8 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track * @param altitudeValue the altitude value * @param timeValue the time value */ - private Location createLocation(double latitudeValue, double longitudeValue, Double altitudeValue, long timeValue) { - Location location = new Location(LocationManager.GPS_PROVIDER); + private TrackPoint createTrackPoint(double latitudeValue, double longitudeValue, Double altitudeValue, long timeValue) { + TrackPoint location = new TrackPoint(LocationManager.GPS_PROVIDER); location.setLatitude(latitudeValue); location.setLongitude(longitudeValue); if (altitudeValue != null) { @@ -443,17 +444,17 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track } /** - * Inserts a location. + * Inserts a trackPoint. * - * @param location the location + * @param trackPoint the trackPoint */ - private void insertLocation(Location location) { + private void insertLocation(TrackPoint trackPoint) { if (trackData.tripStatisticsUpdater == null) { - trackData.tripStatisticsUpdater = new TripStatisticsUpdater(location.getTime() != -1L ? location.getTime() : trackData.importTime); + trackData.tripStatisticsUpdater = new TripStatisticsUpdater(trackPoint.getTime() != -1L ? trackPoint.getTime() : trackData.importTime); } - trackData.tripStatisticsUpdater.addLocation(location, recordingDistanceInterval); + trackData.tripStatisticsUpdater.addTrackPoint(trackPoint, recordingDistanceInterval); - trackData.bufferedLocations[trackData.numBufferedLocations] = location; + trackData.bufferedTrackPoints[trackData.numBufferedLocations] = trackPoint; trackData.numBufferedLocations++; trackData.numberOfLocations++; @@ -471,7 +472,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track if (data.numBufferedLocations <= 0) { return; } - contentProviderUtils.bulkInsertTrackPoint(data.bufferedLocations, data.numBufferedLocations, data.track.getId()); + contentProviderUtils.bulkInsertTrackPoint(data.bufferedTrackPoints, data.numBufferedLocations, data.track.getId()); data.numBufferedLocations = 0; } @@ -510,7 +511,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track final long importTime = System.currentTimeMillis(); // The buffered locations - final Location[] bufferedLocations = new Location[MAX_BUFFERED_LOCATIONS]; + final TrackPoint[] bufferedTrackPoints = new TrackPoint[MAX_BUFFERED_LOCATIONS]; // The number of buffered locations int numBufferedLocations = 0; diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporter.java index 0ac638d90..5497e11f3 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporter.java @@ -17,13 +17,13 @@ package de.dennisguse.opentracks.io.file.importer; import android.content.Context; -import android.location.Location; import androidx.annotation.VisibleForTesting; import org.xml.sax.Attributes; import org.xml.sax.SAXException; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.provider.ContentProviderUtils; /** @@ -155,11 +155,11 @@ public class GpxFileTrackImporter extends AbstractFileTrackImporter { * On track point end. */ private void onTrackPointEnd() throws SAXException { - Location location = getTrackPoint(); - if (location == null) { + TrackPoint trackPoint = getTrackPoint(); + if (trackPoint == null) { return; } - insertTrackPoint(location); + insertTrackPoint(trackPoint); } /** diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/KmlFileTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/KmlFileTrackImporter.java index fa721fc01..ece2647fe 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/KmlFileTrackImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/KmlFileTrackImporter.java @@ -17,7 +17,6 @@ package de.dennisguse.opentracks.io.file.importer; import android.content.Context; -import android.location.Location; import android.net.Uri; import android.util.Log; @@ -65,7 +64,7 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter { private boolean trackStarted = false; private String sensorType; - private ArrayList locationList; + private ArrayList trackPoints; private ArrayList cadenceList; private ArrayList heartRateList; private ArrayList powerList; @@ -213,7 +212,7 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter { @Override protected void onTrackSegmentStart() { super.onTrackSegmentStart(); - locationList = new ArrayList<>(); + trackPoints = new ArrayList<>(); heartRateList = new ArrayList<>(); cadenceList = new ArrayList<>(); powerList = new ArrayList<>(); @@ -224,8 +223,8 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter { */ private void onTrackSegmentEnd() { // Close a track segment by inserting the segment locations - for (int i = 0; i < locationList.size(); i++) { - Location location = locationList.get(i); + for (int i = 0; i < trackPoints.size(); i++) { + TrackPoint trackPoint = trackPoints.get(i); boolean hasSensorData = false; float heartrate = SensorDataSet.DATA_UNAVAILABLE; @@ -246,9 +245,9 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter { } if (!hasSensorData) { - insertTrackPoint(location); + insertTrackPoint(trackPoint); } else { - TrackPoint sensorDataSetLocation = new TrackPoint(location, new SensorDataSet(heartrate, cadence, power, SensorDataSet.DATA_UNAVAILABLE, location.getTime())); + TrackPoint sensorDataSetLocation = new TrackPoint(trackPoint, new SensorDataSet(heartrate, cadence, power, SensorDataSet.DATA_UNAVAILABLE, trackPoint.getTime())); insertTrackPoint(sensorDataSetLocation); } } @@ -270,11 +269,11 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter { latitude = parts[1]; altitude = parts.length == 3 ? parts[2] : null; - Location location = getTrackPoint(); + TrackPoint location = getTrackPoint(); if (location == null) { return; } - locationList.add(location); + trackPoints.add(location); time = null; } diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java index f77670f29..571b1f91a 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java @@ -43,7 +43,6 @@ import de.dennisguse.opentracks.TrackDetailActivity; import de.dennisguse.opentracks.TrackListActivity; import de.dennisguse.opentracks.content.data.Track; import de.dennisguse.opentracks.content.data.TrackPoint; -import de.dennisguse.opentracks.content.data.TrackPointsColumns; import de.dennisguse.opentracks.content.data.Waypoint; import de.dennisguse.opentracks.content.provider.ContentProviderUtils; import de.dennisguse.opentracks.content.provider.CustomContentProvider; @@ -140,7 +139,7 @@ public class TrackRecordingService extends Service { private BluetoothRemoteSensorManager remoteSensorManager; private TripStatisticsUpdater trackTripStatisticsUpdater; - private Location lastLocation; + private TrackPoint lastTrackPoint; private boolean currentSegmentHasLocation; private boolean isIdle; @@ -296,9 +295,9 @@ public class TrackRecordingService extends Service { name = getString(R.string.marker_name_format, nextWaypointNumber + 1); } - Location location = getLastValidTrackPointInCurrentSegment(recordingTrackId); - if (location == null) { - Log.i(TAG, "Could not create a waypoint as location is unknown."); + TrackPoint trackPoint = getLastValidTrackPointInCurrentSegment(recordingTrackId); + if (trackPoint == null) { + Log.i(TAG, "Could not create a waypoint as trackPoint is unknown."); return -1L; } @@ -312,7 +311,7 @@ public class TrackRecordingService extends Service { long duration = stats.getTotalTime(); // Insert waypoint - Waypoint waypoint = new Waypoint(name, description, category, icon, recordingTrackId, length, duration, location, photoUrl); + Waypoint waypoint = new Waypoint(name, description, category, icon, recordingTrackId, length, duration, trackPoint, photoUrl); Uri uri = contentProviderUtils.insertWaypoint(waypoint); return ContentUris.parseId(uri); } @@ -380,7 +379,7 @@ public class TrackRecordingService extends Service { trackTripStatisticsUpdater = new TripStatisticsUpdater(tripStatistics.getStartTime()); try (TrackPointIterator locationIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), -1L, false, TrackPointFactory.DEFAULT_LOCATION_FACTORY)) { - trackTripStatisticsUpdater.addLocation(locationIterator, recordingDistanceInterval); + trackTripStatisticsUpdater.addTrackPoint(locationIterator, recordingDistanceInterval); } catch (RuntimeException e) { Log.e(TAG, "RuntimeException", e); } @@ -400,11 +399,7 @@ public class TrackRecordingService extends Service { // Update database Track track = contentProviderUtils.getTrack(recordingTrackId); if (track != null) { - Location resume = new Location(LocationManager.GPS_PROVIDER); - resume.setLongitude(0); - resume.setLatitude(TrackPointsColumns.RESUME_LATITUDE); - resume.setTime(System.currentTimeMillis()); - insertLocation(track, resume, null); + insertTrackPoint(track, TrackPoint.createResume(), null); } startRecording(); @@ -417,7 +412,7 @@ public class TrackRecordingService extends Service { // Update instance variables remoteSensorManager = new BluetoothRemoteSensorManager(this); remoteSensorManager.start(); - lastLocation = null; + lastTrackPoint = null; currentSegmentHasLocation = false; isIdle = false; @@ -457,7 +452,7 @@ public class TrackRecordingService extends Service { if (track != null) { // If not paused, add the last location if (!paused) { - insertLocation(track, lastLocation, getLastValidTrackPointInCurrentSegment(trackId)); + insertTrackPoint(track, lastTrackPoint, getLastValidTrackPointInCurrentSegment(trackId)); // Update the recording track time updateRecordingTrack(track); @@ -485,13 +480,9 @@ public class TrackRecordingService extends Service { // Update database Track track = contentProviderUtils.getTrack(recordingTrackId); if (track != null) { - insertLocation(track, lastLocation, getLastValidTrackPointInCurrentSegment(track.getId())); + insertTrackPoint(track, lastTrackPoint, getLastValidTrackPointInCurrentSegment(track.getId())); - Location pause = new Location(LocationManager.GPS_PROVIDER); - pause.setLongitude(0); - pause.setLatitude(TrackPointsColumns.PAUSE_LATITUDE); - pause.setTime(System.currentTimeMillis()); - insertLocation(track, pause, null); + insertTrackPoint(track, TrackPoint.createPause(), null); } endRecording(false); @@ -513,7 +504,7 @@ public class TrackRecordingService extends Service { remoteSensorManager.stop(); remoteSensorManager = null; } - lastLocation = null; + lastTrackPoint = null; stopGps(trackStopped); } @@ -540,7 +531,7 @@ public class TrackRecordingService extends Service { * @param trackId the track id * @return the location or null */ - private Location getLastValidTrackPointInCurrentSegment(long trackId) { + private TrackPoint getLastValidTrackPointInCurrentSegment(long trackId) { if (!currentSegmentHasLocation) { return null; } @@ -590,7 +581,7 @@ public class TrackRecordingService extends Service { location.setTime(System.currentTimeMillis()); } - Location lastValidTrackPoint = getLastValidTrackPointInCurrentSegment(track.getId()); + TrackPoint lastValidTrackPoint = getLastValidTrackPointInCurrentSegment(track.getId()); long idleTime = 0L; if (lastValidTrackPoint != null && location.getTime() > lastValidTrackPoint.getTime()) { idleTime = location.getTime() - lastValidTrackPoint.getTime(); @@ -600,77 +591,69 @@ public class TrackRecordingService extends Service { registerLocationListener(); } - SensorDataSet sensorDataSet = getSensorDataSet(); - if (sensorDataSet != null) { - location = new TrackPoint(location, sensorDataSet); - } + TrackPoint trackPoint = new TrackPoint(location, getSensorDataSet()); // Always insert the first segment location if (!currentSegmentHasLocation) { - insertLocation(track, location, null); + insertTrackPoint(track, trackPoint, null); currentSegmentHasLocation = true; - lastLocation = location; + lastTrackPoint = trackPoint; return; } if (!LocationUtils.isValidLocation(lastValidTrackPoint)) { // Should not happen. The current segment should have a location. Just insert the current location. - insertLocation(track, location, null); - lastLocation = location; + insertTrackPoint(track, trackPoint, null); + lastTrackPoint = trackPoint; return; } double distanceToLastTrackLocation = location.distanceTo(lastValidTrackPoint); if (distanceToLastTrackLocation > maxRecordingDistance) { - insertLocation(track, lastLocation, lastValidTrackPoint); + insertTrackPoint(track, lastTrackPoint, lastValidTrackPoint); + insertTrackPoint(track, TrackPoint.createPause(), null); - Location pause = new Location(LocationManager.GPS_PROVIDER); - pause.setLongitude(0); - pause.setLatitude(TrackPointsColumns.PAUSE_LATITUDE); - pause.setTime(lastLocation.getTime()); - insertLocation(track, pause, null); - - insertLocation(track, location, null); + insertTrackPoint(track, trackPoint, null); isIdle = false; - } else if (sensorDataSet != null || distanceToLastTrackLocation >= recordingDistanceInterval) { - insertLocation(track, lastLocation, lastValidTrackPoint); - insertLocation(track, location, null); + } else if (trackPoint.getSensorDataSet() != null || distanceToLastTrackLocation >= recordingDistanceInterval) { + insertTrackPoint(track, lastTrackPoint, lastValidTrackPoint); + insertTrackPoint(track, trackPoint, null); isIdle = false; } else if (!isIdle && location.hasSpeed() && location.getSpeed() < MAX_NO_MOVEMENT_SPEED) { - insertLocation(track, lastLocation, lastValidTrackPoint); - insertLocation(track, location, null); + insertTrackPoint(track, lastTrackPoint, lastValidTrackPoint); + insertTrackPoint(track, trackPoint, null); isIdle = true; } else if (isIdle && location.hasSpeed() && location.getSpeed() >= MAX_NO_MOVEMENT_SPEED) { - insertLocation(track, lastLocation, lastValidTrackPoint); - insertLocation(track, location, null); + insertTrackPoint(track, lastTrackPoint, lastValidTrackPoint); + insertTrackPoint(track, trackPoint, null); isIdle = false; } else { Log.d(TAG, "Not recording location, idle"); } - lastLocation = location; + lastTrackPoint = trackPoint; } /** - * Inserts a location. + * Inserts a trackPoint. * * @param track the track - * @param location the location + * @param trackPoint the trackPoint * @param lastValidTrackPoint the last valid track point, can be null */ - private void insertLocation(Track track, Location location, Location lastValidTrackPoint) { - if (location == null) { - Log.w(TAG, "Ignore insertLocation. location is null."); + private void insertTrackPoint(Track track, TrackPoint trackPoint, Location lastValidTrackPoint) { + if (trackPoint == null) { + Log.w(TAG, "Ignore insertLocation. trackPoint is null."); return; } // Do not insert if inserted already - if (lastValidTrackPoint != null && lastValidTrackPoint.getTime() == location.getTime()) { - Log.w(TAG, "Ignore insertLocation. location time same as last valid track point time."); + if (lastValidTrackPoint != null && lastValidTrackPoint.getTime() == trackPoint.getTime()) { + Log.w(TAG, "Ignore insertLocation. trackPoint time same as last valid track point time."); return; } try { - contentProviderUtils.insertTrackPoint(location, track.getId()); - trackTripStatisticsUpdater.addLocation(location, recordingDistanceInterval); + contentProviderUtils.insertTrackPoint(trackPoint, track.getId()); + trackTripStatisticsUpdater.addTrackPoint(trackPoint, recordingDistanceInterval); updateRecordingTrack(track); } catch (SQLiteException e) { /* diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceBinder.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceBinder.java index 19eb2723e..7e0a5c91c 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceBinder.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceBinder.java @@ -1,9 +1,8 @@ package de.dennisguse.opentracks.services; -import android.location.Location; - import androidx.annotation.VisibleForTesting; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.sensor.SensorDataSet; /** @@ -83,8 +82,8 @@ class TrackRecordingServiceBinder extends android.os.Binder implements TrackReco @VisibleForTesting @Override - public void insertTrackPoint(Location location) { - trackRecordingService.onLocationChangedAsync(location); + public void insertTrackPoint(TrackPoint trackPoint) { + trackRecordingService.onLocationChangedAsync(trackPoint); } @Override diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceInterface.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceInterface.java index c7e01191f..2e70454b7 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceInterface.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceInterface.java @@ -15,10 +15,9 @@ */ package de.dennisguse.opentracks.services; -import android.location.Location; - import androidx.annotation.VisibleForTesting; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.sensor.SensorDataSet; /** @@ -101,10 +100,10 @@ public interface TrackRecordingServiceInterface { * When recording a track, GPS locations are automatically inserted. This is used for * inserting special track points or for testing. * - * @param location the track point to be inserted + * @param trackPoint the track point to be inserted */ @VisibleForTesting - void insertTrackPoint(Location location); + void insertTrackPoint(TrackPoint trackPoint); /** * Gets the current sensor data. Returns null if there is no data. diff --git a/src/main/java/de/dennisguse/opentracks/stats/TripStatisticsUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/TripStatisticsUpdater.java index 2900d0979..945a0468f 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/TripStatisticsUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/TripStatisticsUpdater.java @@ -21,6 +21,7 @@ import android.util.Log; import androidx.annotation.VisibleForTesting; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.data.TrackPointsColumns; import de.dennisguse.opentracks.content.provider.TrackPointIterator; import de.dennisguse.opentracks.util.LocationUtils; @@ -122,24 +123,24 @@ public class TripStatisticsUpdater { } /** - * Adds a location. - * TODO: This assume location has a valid time. + * Adds a trackPoint. + * TODO: This assume trackPoint has a valid time. * - * @param location the location + * @param trackPoint the trackPoint * @param minRecordingDistance the min recording distance */ - public void addLocation(Location location, int minRecordingDistance) { + public void addTrackPoint(TrackPoint trackPoint, int minRecordingDistance) { // Always update time - updateTime(location.getTime()); - if (!LocationUtils.isValidLocation(location)) { + updateTime(trackPoint.getTime()); + if (!LocationUtils.isValidLocation(trackPoint)) { // Either pause or resume marker - if (location.getLatitude() == TrackPointsColumns.PAUSE_LATITUDE) { + if (trackPoint.getLatitude() == TrackPointsColumns.PAUSE_LATITUDE) { if (lastLocation != null && lastMovingLocation != null && lastLocation != lastMovingLocation) { currentSegment.addTotalDistance(lastMovingLocation.distanceTo(lastLocation)); } tripStatistics.merge(currentSegment); } - currentSegment = init(location.getTime()); + currentSegment = init(trackPoint.getTime()); lastLocation = null; lastMovingLocation = null; elevationBuffer.reset(); @@ -150,23 +151,23 @@ public class TripStatisticsUpdater { } //TODO Use Barometer to compute elevation gain. - double elevationDifference = location.hasAltitude() ? updateElevation(location.getAltitude()) : 0.0; + double elevationDifference = trackPoint.hasAltitude() ? updateElevation(trackPoint.getAltitude()) : 0.0; if (lastLocation == null || lastMovingLocation == null) { - lastLocation = location; - lastMovingLocation = location; + lastLocation = trackPoint; + lastMovingLocation = trackPoint; return; } - double movingDistance = lastMovingLocation.distanceTo(location); - if (movingDistance < minRecordingDistance && (!location.hasSpeed() || location.getSpeed() < MAX_NO_MOVEMENT_SPEED)) { + double movingDistance = lastMovingLocation.distanceTo(trackPoint); + if (movingDistance < minRecordingDistance && (!trackPoint.hasSpeed() || trackPoint.getSpeed() < MAX_NO_MOVEMENT_SPEED)) { speedBuffer.reset(); - lastLocation = location; + lastLocation = trackPoint; return; } - long movingTime = location.getTime() - lastLocation.getTime(); + long movingTime = trackPoint.getTime() - lastLocation.getTime(); if (movingTime < 0) { - lastLocation = location; + lastLocation = trackPoint; return; } @@ -177,22 +178,22 @@ public class TripStatisticsUpdater { currentSegment.addMovingTime(movingTime); // Update grade - double run = lastLocation.distanceTo(location); + double run = lastLocation.distanceTo(trackPoint); updateGrade(run, elevationDifference); // Update max speed - if (location.hasSpeed() && lastLocation.hasSpeed()) { - updateSpeed(location.getTime(), location.getSpeed(), lastLocation.getTime(), lastLocation.getSpeed()); + if (trackPoint.hasSpeed() && lastLocation.hasSpeed()) { + updateSpeed(trackPoint.getTime(), trackPoint.getSpeed(), lastLocation.getTime(), lastLocation.getSpeed()); } - lastLocation = location; - lastMovingLocation = location; + lastLocation = trackPoint; + lastMovingLocation = trackPoint; } - public void addLocation(TrackPointIterator iterator, int minRecordingDistance) { + public void addTrackPoint(TrackPointIterator iterator, int minRecordingDistance) { while (iterator.hasNext()) { - Location location = iterator.next(); - addLocation(location, minRecordingDistance); + TrackPoint location = iterator.next(); + addTrackPoint(location, minRecordingDistance); } } diff --git a/src/main/java/de/dennisguse/opentracks/util/LocationUtils.java b/src/main/java/de/dennisguse/opentracks/util/LocationUtils.java index 43598a07c..349506bd7 100644 --- a/src/main/java/de/dennisguse/opentracks/util/LocationUtils.java +++ b/src/main/java/de/dennisguse/opentracks/util/LocationUtils.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Stack; import de.dennisguse.opentracks.content.data.Track; +import de.dennisguse.opentracks.content.data.TrackPoint; /** * Utility class for decimating tracks at a given level of precision. @@ -84,16 +85,16 @@ public class LocationUtils { } /** - * Decimates the given locations for a given zoom level. + * Decimates the given trackPoints for a given zoom level. * This uses a Douglas-Peucker decimation algorithm. * * @param tolerance in meters - * @param locations input + * @param trackPoints input * @param decimated output */ //TODO What was it used for? Sharing data with other apps? - private static void decimate(double tolerance, List locations, List decimated) { - final int n = locations.size(); + private static void decimate(double tolerance, List trackPoints, List decimated) { + final int n = trackPoints.size(); if (n < 1) { return; } @@ -115,7 +116,7 @@ public class LocationUtils { maxDist = 0; for (idx = current[0] + 1; idx < current[1]; ++idx) { dist = LocationUtils.distance( - locations.get(idx), locations.get(current[0]), locations.get(current[1])); + trackPoints.get(idx), trackPoints.get(current[0]), trackPoints.get(current[1])); if (dist > maxDist) { maxDist = dist; maxIdx = idx; @@ -134,7 +135,7 @@ public class LocationUtils { int i = 0; idx = 0; decimated.clear(); - for (Location l : locations) { + for (TrackPoint l : trackPoints) { if (dists[idx] != 0) { decimated.add(l); i++; @@ -151,9 +152,9 @@ public class LocationUtils { * @param precision desired precision in meters */ public static void decimate(Track track, double precision) { - ArrayList decimated = new ArrayList<>(); - decimate(precision, track.getLocations(), decimated); - track.setLocations(decimated); + ArrayList decimated = new ArrayList<>(); + decimate(precision, track.getTrackPoints(), decimated); + track.setTrackPoints(decimated); } /**