diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/CustomContentProviderUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/content/CustomContentProviderUtilsTest.java index 546662d79..e77525207 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/content/CustomContentProviderUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/content/CustomContentProviderUtilsTest.java @@ -827,7 +827,7 @@ public class CustomContentProviderUtilsTest { * @param numPoints the location number in the track * @return the simulated track */ - private Track getTrack(long id, int numPoints) { + public static Track getTrack(long id, int numPoints) { Track track = new Track(); track.setId(id); track.setName("Test: " + id); @@ -844,7 +844,7 @@ public class CustomContentProviderUtilsTest { * @param i the index to set the value of location. * @return created location */ - private Location createLocation(int i) { + private 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); 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 new file mode 100644 index 000000000..0de25837b --- /dev/null +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java @@ -0,0 +1,122 @@ +package de.dennisguse.opentracks.io.file.importer; + +import android.content.Context; +import android.location.Location; + +import androidx.test.core.app.ApplicationProvider; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; + +import de.dennisguse.opentracks.content.ContentProviderUtils; +import de.dennisguse.opentracks.content.CustomContentProviderUtilsTest; +import de.dennisguse.opentracks.content.data.Track; +import de.dennisguse.opentracks.io.file.TrackFileFormat; +import de.dennisguse.opentracks.io.file.exporter.TrackExporter; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +@RunWith(JUnit4.class) +public class ExportImportTest { + + private Context context = ApplicationProvider.getApplicationContext(); + + private ContentProviderUtils contentProviderUtils = new ContentProviderUtils(context); + + private static final String TRACK_ICON = "the track icon"; + private static final String TRACK_CATEGORY = "the category"; + private static final String TRACK_DESCRIPTION = "the description"; + private long exportTrackId = System.currentTimeMillis(); + private long importTrackId; + + @Before + public void setUp() { + Track track = CustomContentProviderUtilsTest.getTrack(exportTrackId, 150); + track.setIcon(TRACK_ICON); + track.setCategory(TRACK_CATEGORY); + track.setDescription(TRACK_DESCRIPTION); + contentProviderUtils.insertTrack(track); + contentProviderUtils.bulkInsertTrackPoint(track.getLocations().toArray(new Location[0]), track.getLocations().size(), track.getId()); + } + + @After + public void tearDown() { + contentProviderUtils.deleteTrack(context, exportTrackId); + contentProviderUtils.deleteTrack(context, importTrackId); + } + + @Test + public void kml_with_trackdetail() { + // given + Track track = contentProviderUtils.getTrack(exportTrackId); + + TrackFileFormat trackFileFormat = TrackFileFormat.KML_WITH_TRACKDETAIL; + TrackExporter trackExporter = trackFileFormat.newTrackExporter(context, new Track[]{track}, null); + + // when + + // 1. export + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + trackExporter.writeTrack(context, outputStream); + + // 2. import + InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); + AbstractFileTrackImporter trackImporter = new KmlFileTrackImporter(context, -1L); + importTrackId = trackImporter.importFile(inputStream); + + // then + Track trackImported = contentProviderUtils.getTrack(importTrackId); + assertNotNull(trackImported); + assertEquals(track.getLocations(), trackImported.getLocations()); + assertEquals(track.getCategory(), trackImported.getCategory()); + assertEquals(track.getDescription(), trackImported.getDescription()); + assertEquals(track.getName(), trackImported.getName()); + assertEquals(track.getIcon(), trackImported.getIcon()); + + //TODO Check (relative/absolute) time of trackpoints + //TODO Check marker/waypoints + //TODO Check tripstatistics + } + + @Test + public void gpx() { + // given + Track track = contentProviderUtils.getTrack(exportTrackId); + + TrackFileFormat trackFileFormat = TrackFileFormat.GPX; + TrackExporter trackExporter = trackFileFormat.newTrackExporter(context, new Track[]{track}, null); + + // when + + // 1. export + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + trackExporter.writeTrack(context, outputStream); + + // 2. import + InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); + AbstractFileTrackImporter trackImporter = new GpxFileTrackImporter(context, contentProviderUtils); + importTrackId = trackImporter.importFile(inputStream); + + // then + Track trackImported = contentProviderUtils.getTrack(importTrackId); + assertNotNull(trackImported); + assertEquals(track.getLocations(), trackImported.getLocations()); + assertEquals(track.getCategory(), trackImported.getCategory()); + assertEquals(track.getDescription(), trackImported.getDescription()); + assertEquals(track.getName(), trackImported.getName()); + + //TODO exporting and importing a track icon is not yet supported by GpxTrackWriter. + //assertEquals(track.getIcon(), trackImported.getIcon()); + //TODO Check (relative/absolute) time of trackpoints + //TODO Check marker/waypoints + //TODO Check tripstatistics + } +} \ No newline at end of file diff --git a/src/main/java/de/dennisguse/opentracks/content/data/WaypointsColumns.java b/src/main/java/de/dennisguse/opentracks/content/data/WaypointsColumns.java index 0e90987e3..f444f38e5 100644 --- a/src/main/java/de/dennisguse/opentracks/content/data/WaypointsColumns.java +++ b/src/main/java/de/dennisguse/opentracks/content/data/WaypointsColumns.java @@ -40,7 +40,8 @@ public interface WaypointsColumns extends BaseColumns { String CATEGORY = "category"; // waypoint category String ICON = "icon"; // waypoint icon String TRACKID = "trackid"; // track id - String TYPE = "type"; // type + @Deprecated //Unused + String TYPE = "type"; // type String LENGTH = "length"; // length of the track (without smoothing) String DURATION = "duration"; // total duration of the track (not from last waypoint) String STARTTIME = "starttime"; // start time of the trip statistics 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 8ae0af347..e1294884d 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 @@ -198,6 +198,7 @@ public class KmlTrackWriter implements TrackWriter { if (exportTrackDetail) { printWriter.println("" + StringUtils.formatCData(track.getName()) + ""); printWriter.println("" + StringUtils.formatCData(track.getDescription()) + ""); + printWriter.println("" + StringUtils.formatCData(track.getIcon()) + ""); } printWriter.println("#" + TRACK_STYLE + ""); 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 7c20f00b7..44c2d8225 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 @@ -69,12 +69,13 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track private final ContentProviderUtils contentProviderUtils; private final int recordingDistanceInterval; - private final List trackIds; - private final List waypoints; + private final List trackIds = new ArrayList<>(); + private final List waypoints = new ArrayList<>(); // The current element content //TODO Should be made private and getter be used by child classes. protected String content; + protected String icon; protected String name; protected String description; protected String category; @@ -102,8 +103,6 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track this.importTrackId = importTrackId; this.contentProviderUtils = contentProviderUtils; this.recordingDistanceInterval = PreferencesUtils.getRecordingDistanceInterval(context); - trackIds = new ArrayList<>(); - waypoints = new ArrayList<>(); } @Override @@ -250,7 +249,12 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track } if (category != null) { trackData.track.setCategory(category); - trackData.track.setIcon(TrackIconUtils.getIconValue(context, category)); + //TODO remove when GPX and KML support reading this property. + if (icon == null) + trackData.track.setIcon(TrackIconUtils.getIconValue(context, category)); + } + if (icon != null) { + trackData.track.setIcon(icon); } if (trackData.tripStatisticsUpdater == null) { trackData.tripStatisticsUpdater = new TripStatisticsUpdater(trackData.importTime); @@ -495,6 +499,7 @@ abstract class AbstractFileTrackImporter extends DefaultHandler implements Track * * @author Jimmy Shih */ + // TODO Why private inner class? private class TrackData { // The current track Track track = new Track(); 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 938f9214d..6af559b2e 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 @@ -46,6 +46,7 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter { private static final String TAG_COORDINATES = "coordinates"; private static final String TAG_DESCRIPTION = "description"; + private static final String TAG_ICON = "icon"; private static final String TAG_GX_COORD = "gx:coord"; private static final String TAG_GX_MULTI_TRACK = "gx:MultiTrack"; private static final String TAG_GX_SIMPLE_ARRAY_DATA = "gx:SimpleArrayData"; @@ -135,6 +136,10 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter { if (content != null) { description = content.trim(); } + } else if (localName.equals(TAG_ICON)) { + if (content != null) { + icon = content.trim(); + } } else if (localName.equals(TAG_VALUE)) { if (content != null) { category = content.trim(); @@ -163,6 +168,7 @@ public class KmlFileTrackImporter extends AbstractFileTrackImporter { private void onWaypointStart() { // Reset all Placemark variables name = null; + icon = null; description = null; category = null; photoUrl = null;