diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java
index 620d5d037..806433dde 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java
@@ -45,12 +45,11 @@ public class GPXExporter implements ActivityTrackExporter {
private static final String NS_GPX_URI = "http://www.topografix.com/GPX/1/1";
private static final String NS_GPX_PREFIX = "";
private static final String NS_TRACKPOINT_EXTENSION = "gpxtpx";
- private static final String NS_TRACKPOINT_EXTENSION_URI = "http://www.garmin.com/xmlschemas/TrackPointExtension/v1";
+ private static final String NS_TRACKPOINT_EXTENSION_URI = "https://www8.garmin.com/xmlschemas/TrackPointExtensionv2.xsd";
private static final String NS_XSI_URI = "http://www.w3.org/2001/XMLSchema-instance";
private static final String TOPOGRAFIX_NAMESPACE_XSD = "http://www.topografix.com/GPX/1/1/gpx.xsd";
private static final String OPENTRACKS_PREFIX = "opentracks";
private static final String OPENTRACKS_NAMESPACE_URI = "http://opentracksapp.com/xmlschemas/v1";
- private static final String OPENTRACKS_NAMESPACE_XSD = "http://opentracksapp.com/xmlschemas/OpenTracks_v1.xsd";
private String creator;
private boolean includeHeartRate = true;
@@ -75,9 +74,7 @@ public class GPXExporter implements ActivityTrackExporter {
} else {
ser.attribute(null, "creator", GBApplication.app().getNameAndVersion());
}
- ser.attribute(NS_XSI_URI, "schemaLocation", NS_GPX_URI + " "
- + TOPOGRAFIX_NAMESPACE_XSD + " "
- + OPENTRACKS_NAMESPACE_URI + " " + OPENTRACKS_NAMESPACE_XSD);
+ ser.attribute(NS_XSI_URI, "schemaLocation",NS_GPX_URI + " " + TOPOGRAFIX_NAMESPACE_XSD);
exportMetadata(ser, track);
exportTrack(ser, track);
@@ -146,10 +143,10 @@ public class GPXExporter implements ActivityTrackExporter {
}
ser.startTag(NS_GPX_URI, "trkpt");
// lon and lat attributes do not have an explicit namespace
- ser.attribute(null, "lon", formatLocation(location.getLongitude()));
- ser.attribute(null, "lat", formatLocation(location.getLatitude()));
+ ser.attribute(null, "lon", formatDouble(location.getLongitude()));
+ ser.attribute(null, "lat", formatDouble(location.getLatitude()));
if (location.getAltitude() != GPSCoordinate.UNKNOWN_ALTITUDE) {
- ser.startTag(NS_GPX_URI, "ele").text(formatLocation(location.getAltitude())).endTag(NS_GPX_URI, "ele");
+ ser.startTag(NS_GPX_URI, "ele").text(formatDouble(location.getAltitude())).endTag(NS_GPX_URI, "ele");
}
ser.startTag(NS_GPX_URI, "time").text(DateTimeUtils.formatIso8601UTC(point.getTime())).endTag(NS_GPX_URI, "time");
String description = point.getDescription();
@@ -170,27 +167,37 @@ public class GPXExporter implements ActivityTrackExporter {
return;
}
+ float speed = point.getSpeed();
+ int cadence = point.getCadence();
int hr = point.getHeartRate();
- if (!HeartRateUtils.getInstance().isValidHeartRateValue(hr)) {
- if (!includeHeartRateOfNearestSample) {
- return;
- }
+ if (!HeartRateUtils.getInstance().isValidHeartRateValue(hr) && includeHeartRateOfNearestSample) {
ActivityPoint closestPointItem = findClosestSensibleActivityPoint(point.getTime(), trackPoints);
- if(closestPointItem == null) {
- return;
+ if (closestPointItem != null) {
+ hr = closestPointItem.getHeartRate();
}
- hr = closestPointItem.getHeartRate();
- if (!HeartRateUtils.getInstance().isValidHeartRateValue(hr)) {
- return;
- }
+ }
+
+ boolean exportHr = HeartRateUtils.getInstance().isValidHeartRateValue(hr) && includeHeartRate;
+
+ if (!exportHr && speed < 0 && cadence < 0) {
+ // No valid data to export in extensions
+ return;
}
ser.startTag(NS_GPX_URI, "extensions");
ser.setPrefix(NS_TRACKPOINT_EXTENSION, NS_TRACKPOINT_EXTENSION_URI);
ser.startTag(NS_TRACKPOINT_EXTENSION_URI, "TrackPointExtension");
- ser.startTag(NS_TRACKPOINT_EXTENSION_URI, "hr").text(String.valueOf(hr)).endTag(NS_TRACKPOINT_EXTENSION_URI, "hr");
+ if (exportHr) {
+ ser.startTag(NS_TRACKPOINT_EXTENSION_URI, "hr").text(String.valueOf(hr)).endTag(NS_TRACKPOINT_EXTENSION_URI, "hr");
+ }
+ if (cadence >= 0) {
+ ser.startTag(NS_TRACKPOINT_EXTENSION_URI, "cad").text(String.valueOf(cadence)).endTag(NS_TRACKPOINT_EXTENSION_URI, "cad");
+ }
+ if (speed >= 0) {
+ ser.startTag(NS_TRACKPOINT_EXTENSION_URI, "speed").text(formatDouble(speed)).endTag(NS_TRACKPOINT_EXTENSION_URI, "speed");
+ }
ser.endTag(NS_TRACKPOINT_EXTENSION_URI, "TrackPointExtension");
ser.endTag(NS_GPX_URI, "extensions");
}
@@ -217,7 +224,7 @@ public class GPXExporter implements ActivityTrackExporter {
return closestPointItem;
}
- private String formatLocation(double value) {
+ private String formatDouble(double value) {
return new BigDecimal(value).setScale(GPSCoordinate.GPS_DECIMAL_DEGREES_SCALE, RoundingMode.HALF_UP).toPlainString();
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityPoint.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityPoint.java
index e36a5cfd4..3767e9fbc 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityPoint.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityPoint.java
@@ -26,11 +26,12 @@ import androidx.annotation.Nullable;
29.2
-
- 11
- 92
- 0
-
+
+ 11
+ 92
+ 0
+ 0.5
+
*/
@@ -39,6 +40,7 @@ public class ActivityPoint {
private GPSCoordinate location;
private int heartRate;
private float speed = -1;
+ private int cadence = -1;
// e.g. to describe a pause during the activity
private @Nullable String description;
@@ -90,4 +92,12 @@ public class ActivityPoint {
public void setSpeed(float speed) {
this.speed = speed;
}
+
+ public int getCadence() {
+ return cadence;
+ }
+
+ public void setCadence(final int cadence) {
+ this.cadence = cadence;
+ }
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitRecord.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitRecord.java
index 17a165d68..823e52bfa 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitRecord.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitRecord.java
@@ -138,6 +138,9 @@ public class FitRecord extends RecordData {
if (getEnhancedSpeed() != null) {
activityPoint.setSpeed(getEnhancedSpeed().floatValue());
}
+ if (getCadence() != null) {
+ activityPoint.setCadence(getCadence());
+ }
return activityPoint;
}
}
diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/HuamiActivityDetailsParserTest.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/HuamiActivityDetailsParserTest.java
index f0595de8b..2abca82b9 100644
--- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/HuamiActivityDetailsParserTest.java
+++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/HuamiActivityDetailsParserTest.java
@@ -104,6 +104,4 @@ public class HuamiActivityDetailsParserTest extends TestBase {
private InputStream getContents(URL hexFile) throws IOException {
return new HexToBinaryInputStream(hexFile.openStream());
}
-
-
}