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;