Compare commits

...

4 Commits

Author SHA1 Message Date
Dennis Guse 979178a6f1 Bugfix: crash when exporting zero tracks.
Fixes #2285
2026-02-21 14:40:17 +01:00
Dennis Guse a92a1e7838 Bugfix: layout's could not be deleted.
Introduced in e9deebea6c

Fixes #2283
2026-02-19 07:54:50 +01:00
Dennis Guse 8cba53cfe4 Cleanup. 2026-02-17 06:27:11 +01:00
Dennis Guse fcedb9c444 Bugfix: crash when heartrate sensor did not send data continuously.
Introduced in 1a14fed287

Fixes #2281.
2026-02-17 06:26:43 +01:00
12 changed files with 38 additions and 27 deletions
@@ -167,8 +167,11 @@ public class ExportActivity extends AbstractActivity {
new Thread(() -> {
directoryFiles = ExportUtils.getAllFiles(ExportActivity.this, documentFile.getUri());
runOnUiThread(() -> {
createExportTasks(allInOneFile);
nextExport(null);
if (createExportTasks(allInOneFile)) {
nextExport(null);
} else {
onExportEnded();
}
});
}).start();
} else {
@@ -217,8 +220,12 @@ public class ExportActivity extends AbstractActivity {
exportTasks.clear();
}
private void createExportTasks(boolean allInOneFile) {
private boolean createExportTasks(boolean allInOneFile) {
List<Track> tracks = contentProviderUtils.getTracks();
if (tracks.isEmpty()) {
return false;
}
exportTasks = new ArrayList<>();
if (allInOneFile) {
String filename = "OpenTracks-Backup";
@@ -227,6 +234,7 @@ public class ExportActivity extends AbstractActivity {
exportTasks.addAll(tracks.stream().map(it -> new ExportTask(null, trackFileFormat, List.of(it.id()))).toList());
}
trackExportTotalCount = exportTasks.size();
return true;
}
/**
@@ -391,7 +399,7 @@ public class ExportActivity extends AbstractActivity {
/**
* Try to resolve the conflict if user gave the info needed.
* Otherwise shows the buttons and views needed to gives the user the possibility of take a decision.
* Otherwise, shows the buttons and views needed to gives the user the possibility of take a decision.
*
* @return true if it could resolve the conflict or false otherwise.
*/
@@ -14,7 +14,6 @@ import java.time.Instant;
import de.dennisguse.opentracks.data.models.Cadence;
import de.dennisguse.opentracks.data.models.Distance;
import de.dennisguse.opentracks.data.models.HeartRate;
import de.dennisguse.opentracks.data.models.Position;
import de.dennisguse.opentracks.data.models.Speed;
import de.dennisguse.opentracks.sensors.sensorData.AggregatorCyclingCadence;
@@ -186,17 +185,6 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange
return handler;
}
private SensorData<HeartRate> getHeartRate(Instant now) {
SensorData<HeartRate> value = heartRateHandler.getSensorData(now);
if (value != null) {
//TODO Move this check into HeartRateHandler
if (value.data().isValid()) return value;
}
return null;
}
private SensorData<Cadence> getCadence(Instant now) {
{
SensorData<Cadence> value = cyclingCadenceHandler.getSensorData(now);
@@ -263,7 +251,7 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange
gpsSensorData,
getSpeed(now),
getDistance(now),
getHeartRate(now),
heartRateHandler.getSensorData(now),
temperatureHandler.getSensorData(now),
getCadence(now),
cyclingPowerHandler.getSensorData(now),
@@ -34,7 +34,7 @@ public abstract class Aggregator<InputType, OutputType> {
previous = next;
}
protected abstract void computeValue(Raw<InputType> current);
protected abstract void computeValue(@NonNull Raw<InputType> current);
/**
* @return did we process data from a sensor.
@@ -1,5 +1,7 @@
package de.dennisguse.opentracks.sensors.sensorData;
import androidx.annotation.NonNull;
import de.dennisguse.opentracks.data.models.AltitudeGainLoss;
import de.dennisguse.opentracks.data.models.AtmosphericPressure;
import de.dennisguse.opentracks.sensors.PressureSensorUtils;
@@ -13,7 +15,7 @@ public class AggregatorBarometer extends Aggregator<AtmosphericPressure, Altitud
}
@Override
protected void computeValue(Raw<AtmosphericPressure> current) {
protected void computeValue(@NonNull Raw<AtmosphericPressure> current) {
if (previous == null) {
lastAcceptedSensorValue = current.value();
output = new AltitudeGainLoss(0f, 0f);
@@ -2,6 +2,8 @@ package de.dennisguse.opentracks.sensors.sensorData;
import android.util.Log;
import androidx.annotation.NonNull;
import java.time.Duration;
import de.dennisguse.opentracks.data.models.Cadence;
@@ -17,7 +19,7 @@ public class AggregatorCyclingCadence extends Aggregator<CyclingCadenceBluetooth
}
@Override
protected void computeValue(Raw<CyclingCadenceBluetooth.CrankData> current) {
protected void computeValue(@NonNull Raw<CyclingCadenceBluetooth.CrankData> current) {
if (previous == null) {
return;
}
@@ -2,6 +2,8 @@ package de.dennisguse.opentracks.sensors.sensorData;
import android.util.Log;
import androidx.annotation.NonNull;
import java.time.Duration;
import de.dennisguse.opentracks.data.models.Distance;
@@ -20,7 +22,7 @@ public class AggregatorCyclingDistanceSpeed extends Aggregator<CyclingDistanceSp
}
@Override
protected void computeValue(Raw<CyclingDistanceSpeedBluetooth.WheelData> current) {
protected void computeValue(@NonNull Raw<CyclingDistanceSpeedBluetooth.WheelData> current) {
if (previous == null) {
return;
}
@@ -1,5 +1,7 @@
package de.dennisguse.opentracks.sensors.sensorData;
import androidx.annotation.NonNull;
import de.dennisguse.opentracks.data.models.Power;
import de.dennisguse.opentracks.sensors.driver.CyclingPowerBluetooth;
@@ -10,7 +12,7 @@ public class AggregatorCyclingPower extends Aggregator<CyclingPowerBluetooth.Dat
}
@Override
public void computeValue(Raw<CyclingPowerBluetooth.Data> current) {
public void computeValue(@NonNull Raw<CyclingPowerBluetooth.Data> current) {
this.output = current.value().power();
}
}
@@ -2,6 +2,8 @@ package de.dennisguse.opentracks.sensors.sensorData;
import android.location.Location;
import androidx.annotation.NonNull;
import de.dennisguse.opentracks.data.models.Position;
public class AggregatorGPS extends Aggregator<Location, Position> {
@@ -11,7 +13,7 @@ public class AggregatorGPS extends Aggregator<Location, Position> {
}
@Override
protected void computeValue(Raw<Location> current) {
protected void computeValue(@NonNull Raw<Location> current) {
output = Position.of(current.value(), current.time());
}
@@ -1,5 +1,7 @@
package de.dennisguse.opentracks.sensors.sensorData;
import androidx.annotation.NonNull;
import de.dennisguse.opentracks.data.models.HeartRate;
public class AggregatorHeartRate extends Aggregator<HeartRate, HeartRate> {
@@ -9,7 +11,7 @@ public class AggregatorHeartRate extends Aggregator<HeartRate, HeartRate> {
}
@Override
protected void computeValue(Raw<HeartRate> current) {
protected void computeValue(@NonNull Raw<HeartRate> current) {
if (current.value().isValid()) {
this.output = current.value();
}
@@ -19,7 +19,7 @@ public final class AggregatorRunning extends Aggregator<RunningSpeedAndCadenceBl
}
@Override
public void computeValue(Raw<RunningSpeedAndCadenceBluetooth.Data> current) {
public void computeValue(@NonNull Raw<RunningSpeedAndCadenceBluetooth.Data> current) {
if (previous == null) {
return;
}
@@ -1,5 +1,7 @@
package de.dennisguse.opentracks.sensors.sensorData;
import androidx.annotation.NonNull;
import java.time.Duration;
import de.dennisguse.opentracks.data.models.Temperature;
@@ -10,7 +12,7 @@ public class AggregatorTemperature extends Aggregator<Temperature, Temperature>
super(sensorAddress, sensorName);
}
protected void computeValue(Raw<Temperature> current) {
protected void computeValue(@NonNull Raw<Temperature> current) {
this.output = current.value();
}
@@ -5,6 +5,7 @@ import android.util.Log;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@@ -22,7 +23,7 @@ public class RecordingLayoutIO {
public static List<RecordingLayout> fromCsv(@NonNull String csv, @NonNull Resources resources) {
return CsvLayoutUtils.getCsvLines(csv).stream()
.map(line -> RecordingLayoutIO.fromCsvLine(line, resources))
.toList();
.collect(Collectors.toCollection(ArrayList::new));
}
public static RecordingLayout fromCsvLine(@NonNull String csvLine, @NonNull Resources resources) {