forked from upstream-mirrors/OpenTracks
Idle: TrackRecordingManager creates IDLE TrackPoints (import/export GPX/KML).
Fixes of #1187.
This commit is contained in:
@@ -66,6 +66,7 @@ public class TrackPoint {
|
||||
|
||||
public final int type_db;
|
||||
|
||||
|
||||
Type(int type_db) {
|
||||
this.type_db = type_db;
|
||||
}
|
||||
|
||||
@@ -171,6 +171,9 @@ public class GPXTrackExporter implements TrackExporter {
|
||||
sensorPoints.add(trackPoint);
|
||||
}
|
||||
}
|
||||
case IDLE -> {
|
||||
// Not supported as IDLE-TrackPoints have no location.
|
||||
}
|
||||
default ->
|
||||
throw new RuntimeException("Exporting this TrackPoint type is not implemented: " + trackPoint.getType());
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ public class KMLTrackExporter implements TrackExporter {
|
||||
|
||||
public static final String EXTENDED_DATA_TYPE_ACTIVITYTYPE = "type";
|
||||
|
||||
public static final String EXTENDED_DATA_TYPE_TRACKPOINT = "trackpoint_type";
|
||||
public static final String EXTENDED_DATA_TYPE_SPEED = "speed";
|
||||
public static final String EXTENDED_DATA_TYPE_DISTANCE = "distance";
|
||||
public static final String EXTENDED_DATA_TYPE_CADENCE = "cadence";
|
||||
@@ -83,6 +84,9 @@ public class KMLTrackExporter implements TrackExporter {
|
||||
private final ContentProviderUtils contentProviderUtils;
|
||||
|
||||
private PrintWriter printWriter;
|
||||
|
||||
private ArrayList<TrackPoint.Type> trackpointTypeList = new ArrayList<>();
|
||||
|
||||
private final List<Float> speedList = new ArrayList<>();
|
||||
private final List<Float> distanceList = new ArrayList<>();
|
||||
private final List<Float> powerList = new ArrayList<>();
|
||||
@@ -177,12 +181,13 @@ public class KMLTrackExporter implements TrackExporter {
|
||||
writeCloseSegment();
|
||||
wroteSegment = false;
|
||||
}
|
||||
case TRACKPOINT -> {
|
||||
case TRACKPOINT, IDLE -> {
|
||||
if (!wroteSegment) {
|
||||
// Might happen for older data (pre v3.15.0)
|
||||
writeOpenSegment();
|
||||
wroteSegment = true;
|
||||
}
|
||||
|
||||
writeTrackPoint(track.getZoneOffset(), trackPoint);
|
||||
}
|
||||
default ->
|
||||
@@ -309,6 +314,7 @@ public class KMLTrackExporter implements TrackExporter {
|
||||
@VisibleForTesting
|
||||
void writeOpenSegment() {
|
||||
printWriter.println("<Track>");
|
||||
trackpointTypeList.clear();
|
||||
speedList.clear();
|
||||
distanceList.clear();
|
||||
powerList.clear();
|
||||
@@ -324,32 +330,35 @@ public class KMLTrackExporter implements TrackExporter {
|
||||
void writeCloseSegment() {
|
||||
printWriter.println("<ExtendedData>");
|
||||
printWriter.println("<SchemaData schemaUrl=\"#" + SCHEMA_ID + "\">");
|
||||
|
||||
writeTrackPointType(trackpointTypeList);
|
||||
|
||||
if (speedList.stream().anyMatch(Objects::nonNull)) {
|
||||
writeSimpleArrayData(speedList, EXTENDED_DATA_TYPE_SPEED);
|
||||
writeSimpleArraySensorData(speedList, EXTENDED_DATA_TYPE_SPEED);
|
||||
}
|
||||
if (distanceList.stream().anyMatch(Objects::nonNull)) {
|
||||
writeSimpleArrayData(distanceList, EXTENDED_DATA_TYPE_DISTANCE);
|
||||
writeSimpleArraySensorData(distanceList, EXTENDED_DATA_TYPE_DISTANCE);
|
||||
}
|
||||
if (powerList.stream().anyMatch(Objects::nonNull)) {
|
||||
writeSimpleArrayData(powerList, EXTENDED_DATA_TYPE_POWER);
|
||||
writeSimpleArraySensorData(powerList, EXTENDED_DATA_TYPE_POWER);
|
||||
}
|
||||
if (cadenceList.stream().anyMatch(Objects::nonNull)) {
|
||||
writeSimpleArrayData(cadenceList, EXTENDED_DATA_TYPE_CADENCE);
|
||||
writeSimpleArraySensorData(cadenceList, EXTENDED_DATA_TYPE_CADENCE);
|
||||
}
|
||||
if (heartRateList.stream().anyMatch(Objects::nonNull)) {
|
||||
writeSimpleArrayData(heartRateList, EXTENDED_DATA_TYPE_HEART_RATE);
|
||||
writeSimpleArraySensorData(heartRateList, EXTENDED_DATA_TYPE_HEART_RATE);
|
||||
}
|
||||
if (altitudeGainList.stream().anyMatch(Objects::nonNull)) {
|
||||
writeSimpleArrayData(altitudeGainList, EXTENDED_DATA_TYPE_ALTITUDE_GAIN);
|
||||
writeSimpleArraySensorData(altitudeGainList, EXTENDED_DATA_TYPE_ALTITUDE_GAIN);
|
||||
}
|
||||
if (altitudeLossList.stream().anyMatch(Objects::nonNull)) {
|
||||
writeSimpleArrayData(altitudeLossList, EXTENDED_DATA_TYPE_ALTITUDE_LOSS);
|
||||
writeSimpleArraySensorData(altitudeLossList, EXTENDED_DATA_TYPE_ALTITUDE_LOSS);
|
||||
}
|
||||
if (accuracyHorizontal.stream().anyMatch(Objects::nonNull)) {
|
||||
writeSimpleArrayData(accuracyHorizontal, EXTENDED_DATA_TYPE_ACCURACY_HORIZONTAL);
|
||||
writeSimpleArraySensorData(accuracyHorizontal, EXTENDED_DATA_TYPE_ACCURACY_HORIZONTAL);
|
||||
}
|
||||
if (accuracyVertical.stream().anyMatch(Objects::nonNull)) {
|
||||
writeSimpleArrayData(accuracyVertical, EXTENDED_DATA_TYPE_ACCURACY_VERTICAL);
|
||||
writeSimpleArraySensorData(accuracyVertical, EXTENDED_DATA_TYPE_ACCURACY_VERTICAL);
|
||||
}
|
||||
printWriter.println("</SchemaData>");
|
||||
printWriter.println("</ExtendedData>");
|
||||
@@ -360,6 +369,8 @@ public class KMLTrackExporter implements TrackExporter {
|
||||
void writeTrackPoint(ZoneOffset zoneOffset, TrackPoint trackPoint) {
|
||||
printWriter.println("<when>" + getTime(zoneOffset, trackPoint.getLocation()) + "</when>");
|
||||
|
||||
trackpointTypeList.add(trackPoint.getType());
|
||||
|
||||
if (trackPoint.hasLocation()) {
|
||||
printWriter.println("<coord>" + getCoordinates(trackPoint.getLocation(), " ") + "</coord>");
|
||||
} else {
|
||||
@@ -378,13 +389,7 @@ public class KMLTrackExporter implements TrackExporter {
|
||||
accuracyVertical.add(trackPoint.hasVerticalAccuracy() ? (float) trackPoint.getVerticalAccuracy().toM() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the simple array data.
|
||||
*
|
||||
* @param list a list of simple array data
|
||||
* @param name the name of the simple array data
|
||||
*/
|
||||
private void writeSimpleArrayData(List<Float> list, String name) {
|
||||
private void writeSimpleArraySensorData(List<Float> list, String name) {
|
||||
printWriter.println("<SimpleArrayData name=\"" + name + "\">");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Float value = list.get(i);
|
||||
@@ -397,14 +402,14 @@ public class KMLTrackExporter implements TrackExporter {
|
||||
printWriter.println("</SimpleArrayData>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a placemark.
|
||||
*
|
||||
* @param name the name
|
||||
* @param activityType the activityType
|
||||
* @param description the description
|
||||
* @param location the location
|
||||
*/
|
||||
private void writeTrackPointType(List<TrackPoint.Type> list) {
|
||||
printWriter.println("<SimpleArrayData name=\"" + EXTENDED_DATA_TYPE_TRACKPOINT + "\">");
|
||||
for (TrackPoint.Type value : list) {
|
||||
printWriter.println("<value>" + value.name() + "</value>");
|
||||
}
|
||||
printWriter.println("</SimpleArrayData>");
|
||||
}
|
||||
|
||||
private void writePlacemark(String name, String activityType, String description, Location location, ZoneOffset zoneOffset) {
|
||||
if (location != null) {
|
||||
printWriter.println("<Placemark>");
|
||||
|
||||
@@ -94,7 +94,9 @@ public class KmlTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
private final ArrayList<Instant> whenList = new ArrayList<>();
|
||||
private final ArrayList<Location> locationList = new ArrayList<>();
|
||||
|
||||
private String dataType;
|
||||
private String dataType; //Could be converted to an ENUM
|
||||
|
||||
private final ArrayList<String> trackpointTypeList = new ArrayList<>();
|
||||
private final ArrayList<Float> sensorSpeedList = new ArrayList<>();
|
||||
private final ArrayList<Float> sensorDistanceList = new ArrayList<>();
|
||||
private final ArrayList<Float> sensorCadenceList = new ArrayList<>();
|
||||
@@ -287,6 +289,7 @@ public class KmlTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
locationList.clear();
|
||||
whenList.clear();
|
||||
|
||||
trackpointTypeList.clear();
|
||||
sensorSpeedList.clear();
|
||||
sensorDistanceList.clear();
|
||||
sensorHeartRateList.clear();
|
||||
@@ -313,12 +316,14 @@ public class KmlTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
trackPoint.setLocation(location);
|
||||
}
|
||||
|
||||
if (i < trackpointTypeList.size() && trackpointTypeList.get(i) != null) {
|
||||
|
||||
TrackPoint.Type type = TrackPoint.Type.valueOf(trackpointTypeList.get(i));
|
||||
trackPoint.setType(type);
|
||||
}
|
||||
|
||||
if (i < sensorSpeedList.size() && sensorSpeedList.get(i) != null) {
|
||||
trackPoint.setSpeed(Speed.of(sensorSpeedList.get(i)));
|
||||
|
||||
if (TrackPoint.IDLE_SPEED.greaterOrEqualThan(trackPoint.getSpeed())) {
|
||||
trackPoint.setType(TrackPoint.Type.IDLE);
|
||||
}
|
||||
}
|
||||
if (i < sensorDistanceList.size() && sensorDistanceList.get(i) != null) {
|
||||
trackPoint.setSensorDistance(Distance.of(sensorDistanceList.get(i)));
|
||||
@@ -403,6 +408,10 @@ public class KmlTrackImporter extends DefaultHandler implements XMLImporter.Trac
|
||||
}
|
||||
|
||||
private void onExtendedDataValueEnd() throws SAXException {
|
||||
if (dataType.equals(KMLTrackExporter.EXTENDED_DATA_TYPE_TRACKPOINT)) {
|
||||
trackpointTypeList.add(content != null ? content.trim() : null);
|
||||
return;
|
||||
}
|
||||
Float value = null;
|
||||
if (content != null) {
|
||||
content = content.trim();
|
||||
|
||||
@@ -10,6 +10,7 @@ import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.ZoneOffset;
|
||||
@@ -29,7 +30,7 @@ import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||
import de.dennisguse.opentracks.stats.TrackStatisticsUpdater;
|
||||
import de.dennisguse.opentracks.util.TrackNameUtils;
|
||||
|
||||
class TrackRecordingManager implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
public class TrackRecordingManager implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
private static final String TAG = TrackRecordingManager.class.getSimpleName();
|
||||
|
||||
@@ -162,7 +163,8 @@ class TrackRecordingManager implements SharedPreferences.OnSharedPreferenceChang
|
||||
return new Marker.Id(ContentUris.parseId(uri));
|
||||
}
|
||||
|
||||
void onIdle() {
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
|
||||
public void onIdle() {
|
||||
Log.d(TAG, "Becoming idle");
|
||||
onNewTrackPoint(trackPointCreator.createIdle());
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ public class TrackStatisticsUpdater {
|
||||
this.trackStatistics = new TrackStatistics(toCopy.trackStatistics);
|
||||
|
||||
this.lastTrackPoint = toCopy.lastTrackPoint;
|
||||
this.idle = idle;
|
||||
this.idle = toCopy.idle;
|
||||
resetAverageHeartRate();
|
||||
}
|
||||
|
||||
@@ -181,6 +181,7 @@ public class TrackStatisticsUpdater {
|
||||
currentSegment.reset(trackPoint.getTime());
|
||||
|
||||
lastTrackPoint = null;
|
||||
idle = false;
|
||||
resetAverageHeartRate();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user