From 0372f855c918a7319445fd70999d091dc931a182 Mon Sep 17 00:00:00 2001 From: Thomas Kuehne Date: Fri, 24 Apr 2026 18:54:54 +0000 Subject: [PATCH] Garmin: code cleanup in FitImporter / GarminWorkoutParser --- .../devices/garmin/GarminWorkoutParser.java | 123 +++++++++--------- .../devices/garmin/fit/FitImporter.java | 51 ++++---- 2 files changed, 90 insertions(+), 84 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/GarminWorkoutParser.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/GarminWorkoutParser.java index ebc6415dd3..28217441bf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/GarminWorkoutParser.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/garmin/GarminWorkoutParser.java @@ -20,6 +20,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries. import android.content.Context; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.slf4j.Logger; @@ -54,10 +55,10 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.FitFile; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordData; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.enums.GarminSport; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.exception.FitParseException; -import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionBatteryStatus.BatteryStatus; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionBatteryStatus; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionExerciseCategory.ExerciseCategory; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionMeasurementSystem; -import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionWaterType.WaterType; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.fieldDefinitions.FieldDefinitionWaterType; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitDeviceInfo; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitDeviceStatus; import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages.FitDiveGas; @@ -84,12 +85,19 @@ public class GarminWorkoutParser implements ActivitySummaryParser { private final List timesInZone = new ArrayList<>(); private final List activityPoints = new ArrayList<>(); private List sessionActivityPoints; + @Nullable private FitSession session = null; + @Nullable private FitSport sport = null; + @Nullable private FitUserMetrics userMetrics = null; + @Nullable private FitUserProfile userProfile = null; + @Nullable private FitPhysiologicalMetrics physiologicalMetrics = null; + @Nullable private FitDiveSettings diveSettings = null; + @Nullable private FitDiveSummary diveSummary = null; private final List diveGases = new ArrayList<>(); private final List sets = new ArrayList<>(); @@ -111,7 +119,7 @@ public class GarminWorkoutParser implements ActivitySummaryParser { } @Nullable - public Long getSessionStartTime(){ + public Long getSessionStartTime() { return (session != null) ? session.getStartTime() : null; } @@ -122,7 +130,7 @@ public class GarminWorkoutParser implements ActivitySummaryParser { } @Override - public Workout parseWorkout(BaseActivitySummary summary, final boolean forDetails) { + public Workout parseWorkout(final BaseActivitySummary summary, final boolean forDetails) { if (!forDetails) { // Our parsing is too slow, especially without a RecyclerView return new Workout(summary, ActivitySummaryData.fromJson(summary.getSummaryData())); @@ -211,72 +219,72 @@ public class GarminWorkoutParser implements ActivitySummaryParser { ebikeBatteryEnd = ebikeBattery; } } - } else if (record instanceof FitSession) { - LOG.debug("Session: {}", record); + } else if (record instanceof FitSession fitSession) { + LOG.debug("Session: {}", fitSession); if (session != null) { - LOG.warn("Got multiple sessions - NOT SUPPORTED: {}", record); + LOG.warn("Got multiple sessions - NOT SUPPORTED: {}", fitSession); } else { // We only support 1 session - session = (FitSession) record; + session = fitSession; sessionActivityPoints = (session.toActivityPoints()); } - } else if (record instanceof FitPhysiologicalMetrics) { - LOG.debug("Physiological Metrics: {}", record); - physiologicalMetrics = (FitPhysiologicalMetrics) record; - } else if (record instanceof FitSport) { - LOG.debug("Sport: {}", record); + } else if (record instanceof FitPhysiologicalMetrics fitPhysiologicalMetrics) { + LOG.debug("Physiological Metrics: {}", fitPhysiologicalMetrics); + physiologicalMetrics = fitPhysiologicalMetrics; + } else if (record instanceof FitSport fitSport) { + LOG.debug("Sport: {}", fitSport); if (sport != null) { - LOG.warn("Got multiple sports - NOT SUPPORTED: {}", record); + LOG.warn("Got multiple sports - NOT SUPPORTED: {}", fitSport); } else { // We only support 1 sport - sport = (FitSport) record; + sport = fitSport; } - } else if (record instanceof FitTimeInZone) { - LOG.trace("Time in zone: {}", record); - timesInZone.add((FitTimeInZone) record); - } else if (record instanceof FitSet) { - LOG.trace("Set: {}", record); - sets.add((FitSet) record); - } else if (record instanceof FitLap) { - LOG.trace("Lap: {}", record); - laps.add((FitLap) record); - } else if (record instanceof FitUserProfile) { - LOG.trace("User Profile: {}", record); + } else if (record instanceof FitTimeInZone fitTimeInZone) { + LOG.trace("Time in zone: {}", fitTimeInZone); + timesInZone.add(fitTimeInZone); + } else if (record instanceof FitSet fitSet) { + LOG.trace("Set: {}", fitSet); + sets.add(fitSet); + } else if (record instanceof FitLap fitLap) { + LOG.trace("Lap: {}", fitLap); + laps.add(fitLap); + } else if (record instanceof FitUserProfile fitUserProfile) { + LOG.trace("User Profile: {}", fitUserProfile); if (userProfile != null) { - LOG.warn("Got multiple user profiles - NOT SUPPORTED: {}", record); + LOG.warn("Got multiple user profiles - NOT SUPPORTED: {}", fitUserProfile); } else { // We only support 1 user profile - userProfile = (FitUserProfile) record; + userProfile = fitUserProfile; } } else if (record instanceof FitUserMetrics metrics) { if (userMetrics != null) { - LOG.warn("Got multiple user metrics - NOT SUPPORTED: {}", record); + LOG.warn("Got multiple user metrics - NOT SUPPORTED: {}", metrics); } else { userMetrics = metrics; } } else if (record instanceof FitDiveSummary newDiveSummary) { - LOG.trace("Dive summary: {}", record); + LOG.trace("Dive summary: {}", newDiveSummary); if (diveSummary != null) { Integer referenceMesg = newDiveSummary.getReferenceMesg(); - if(referenceMesg != null && referenceMesg != 18){ + if (referenceMesg != null && referenceMesg != 18) { // prioritize diving session (18) over records like diving laps (19) // wish list for apnea diving: parse the multiple laps (19) return false; } Integer referenceIndex = newDiveSummary.getReferenceIndex(); - if(referenceIndex != null && referenceIndex != 0){ + if (referenceIndex != null && referenceIndex != 0) { // prioritize first session/lap over other session/lap return false; } } diveSummary = newDiveSummary; - } else if (record instanceof FitDiveGas) { - LOG.trace("Dive gas: {}", record); - diveGases.add((FitDiveGas) record); - }else if(record instanceof FitDiveSettings settings){ + } else if (record instanceof FitDiveGas fitDiveGas) { + LOG.trace("Dive gas: {}", fitDiveGas); + diveGases.add(fitDiveGas); + } else if (record instanceof FitDiveSettings settings) { if (diveSettings != null) { - LOG.warn("Got multiple dive settings - NOT SUPPORTED: {}", record); + LOG.warn("Got multiple dive settings - NOT SUPPORTED: {}", settings); } else { diveSettings = settings; } @@ -297,8 +305,8 @@ public class GarminWorkoutParser implements ActivitySummaryParser { if (volt != null && volt != 0) { relevant = true; } else { - BatteryStatus batteryStatus = deviceInfo.getBatteryStatus(); - if (batteryStatus != null && batteryStatus != BatteryStatus.Unknown) { + FieldDefinitionBatteryStatus.BatteryStatus batteryStatus = deviceInfo.getBatteryStatus(); + if (batteryStatus != null && batteryStatus != FieldDefinitionBatteryStatus.BatteryStatus.Unknown) { relevant = true; } } @@ -317,7 +325,7 @@ public class GarminWorkoutParser implements ActivitySummaryParser { return false; } else if (record instanceof FitWorkout fitWorkout) { if (workout != null) { - LOG.warn("Got multiple workout - NOT SUPPORTED: {}", record); + LOG.warn("Got multiple workout - NOT SUPPORTED: {}", fitWorkout); } else { workout = fitWorkout; } @@ -376,10 +384,10 @@ public class GarminWorkoutParser implements ActivitySummaryParser { } if (session.getTotalTimerTime() != null) { - summaryData.add(ACTIVE_SECONDS, session.getTotalTimerTime() / 1000f, UNIT_SECONDS); + summaryData.add(ACTIVE_SECONDS, session.getTotalTimerTime() / 1000.0f, UNIT_SECONDS); } if (session.getTotalDistance() != null) { - summaryData.add(DISTANCE_METERS, session.getTotalDistance() / 100f, UNIT_METERS); + summaryData.add(DISTANCE_METERS, session.getTotalDistance() / 100.0f, UNIT_METERS); } summaryData.add(POOL_LENGTH, session.getPoolLength(), UNIT_METERS); summaryData.add(SWOLF_AVG, session.getAvgSwolf(), UNIT_NONE); @@ -450,7 +458,7 @@ public class GarminWorkoutParser implements ActivitySummaryParser { summaryData.add(SWIM_AVG_CADENCE, session.getAvgSwimCadence(), UNIT_STROKES_PER_LENGTH); Number speedAvg = session.getEnhancedAvgSpeed(); - if(speedAvg == null){ + if (speedAvg == null) { speedAvg = session.getAvgSpeed(); } if (speedAvg != null) { @@ -464,7 +472,7 @@ public class GarminWorkoutParser implements ActivitySummaryParser { } Number speedMax = session.getEnhancedMaxSpeed(); - if(speedMax == null){ + if (speedMax == null) { speedMax = session.getMaxSpeed(); } if (speedMax != null) { @@ -502,7 +510,7 @@ public class GarminWorkoutParser implements ActivitySummaryParser { context.getString( R.string.range_percentage_float, session.getAvgStanceTimeBalance(), - 100f - session.getAvgStanceTimeBalance() + 100.0f - session.getAvgStanceTimeBalance() ) ); } @@ -603,16 +611,16 @@ public class GarminWorkoutParser implements ActivitySummaryParser { final Integer balance = session.getLeftRightBalance(); if (balance != null) { - final float balancePercentage = (balance & 0x3fff) / 100f; + final float balancePercentage = (balance & 0x3fff) / 100.0f; final boolean isRight = (balance & 0x8000) != 0; final float balanceL; final float balanceR; if (isRight) { - balanceL = 100f - balancePercentage; + balanceL = 100.0f - balancePercentage; balanceR = balancePercentage; } else { balanceL = balancePercentage; - balanceR = 100f - balancePercentage; + balanceR = 100.0f - balancePercentage; } summaryData.add( LEFT_RIGHT_BALANCE, @@ -658,7 +666,7 @@ public class GarminWorkoutParser implements ActivitySummaryParser { continue; } final List zoneOrder = Arrays.asList(HR_ZONE_NA, HR_ZONE_WARM_UP, HR_ZONE_EASY, HR_ZONE_AEROBIC, HR_ZONE_THRESHOLD, HR_ZONE_MAXIMUM); - final int[] zoneColors = new int[]{ + final int[] zoneColors = { 0, context.getResources().getColor(R.color.hr_zone_warm_up_color), context.getResources().getColor(R.color.hr_zone_easy_color), @@ -720,7 +728,7 @@ public class GarminWorkoutParser implements ActivitySummaryParser { if (diveSettings.getWaterDensity() != null) { summaryData.add(WATER_TYPE, diveSettings.getWaterDensity(), UNIT_KG_PER_M3); } else { - WaterType waterType = diveSettings.getWaterType(); + FieldDefinitionWaterType.WaterType waterType = diveSettings.getWaterType(); if (waterType != null) { summaryData.add(WATER_TYPE, waterType.toString(context)); } @@ -745,7 +753,7 @@ public class GarminWorkoutParser implements ActivitySummaryParser { summaryData.add(BODY_ENERGY_AT_START, session.getBeginningBodyBattery(), UNIT_PERCENTAGE); summaryData.add(BODY_ENERGY_AT_END, session.getEndingBodyBattery(), UNIT_PERCENTAGE); - summaryData.add(SOLAR_INTENSITY, safeRound(session.getSolarIntensity()), UNIT_PERCENTAGE); + summaryData.add(SOLAR_INTENSITY, session.getSolarIntensity(), UNIT_PERCENTAGE); summaryData.add(BATTERY_GAIN, session.getBatteryGain(), UNIT_SECONDS); if (!diveGases.isEmpty()) { @@ -808,7 +816,7 @@ public class GarminWorkoutParser implements ActivitySummaryParser { final FitDeviceInfo deviceInfo = entry.getValue(); final String device = AntGadget.Companion.NameGadget(deviceInfo); - BatteryStatus rawStatus = deviceInfo.getBatteryStatus(); + FieldDefinitionBatteryStatus.BatteryStatus rawStatus = deviceInfo.getBatteryStatus(); @Nullable final String status; if (rawStatus != null) { status = rawStatus.toString(context); @@ -981,15 +989,8 @@ public class GarminWorkoutParser implements ActivitySummaryParser { return false; } - public Number safeRound(final Number number) { - if (number == null) { - return null; - } - - return Math.round(number.doubleValue()); - } - - private static ActivityKind getActivityKind(Integer sport, Integer subsport) { + @NonNull + private static ActivityKind getActivityKind(@Nullable Integer sport, @Nullable Integer subsport) { // Garmin inReach Mini 2: sport and subsport are missing (null) if (sport == null) { sport = 0; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/FitImporter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/FitImporter.java index 474f8a1169..882e4daefa 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/FitImporter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/FitImporter.java @@ -19,6 +19,9 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit; import android.content.Context; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,8 +55,8 @@ import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminIntensityMinute import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminNapSampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminRespiratoryRateSampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminRestingMetabolicRateSampleProvider; -import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminSleepStatsSampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminSleepStageSampleProvider; +import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminSleepStatsSampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminSpo2SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminStressSampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminWorkoutParser; @@ -66,12 +69,12 @@ import nodomain.freeyourgadget.gadgetbridge.entities.GarminActivitySample; import nodomain.freeyourgadget.gadgetbridge.entities.GarminBodyEnergySample; import nodomain.freeyourgadget.gadgetbridge.entities.GarminEventSample; import nodomain.freeyourgadget.gadgetbridge.entities.GarminHeartRateRestingSample; -import nodomain.freeyourgadget.gadgetbridge.entities.GarminIntensityMinutesSample; -import nodomain.freeyourgadget.gadgetbridge.entities.GarminNapSample; -import nodomain.freeyourgadget.gadgetbridge.entities.GarminRestingMetabolicRateSample; import nodomain.freeyourgadget.gadgetbridge.entities.GarminHrvSummarySample; import nodomain.freeyourgadget.gadgetbridge.entities.GarminHrvValueSample; +import nodomain.freeyourgadget.gadgetbridge.entities.GarminIntensityMinutesSample; +import nodomain.freeyourgadget.gadgetbridge.entities.GarminNapSample; import nodomain.freeyourgadget.gadgetbridge.entities.GarminRespiratoryRateSample; +import nodomain.freeyourgadget.gadgetbridge.entities.GarminRestingMetabolicRateSample; import nodomain.freeyourgadget.gadgetbridge.entities.GarminSleepRestlessMomentsSample; import nodomain.freeyourgadget.gadgetbridge.entities.GarminSleepStageSample; import nodomain.freeyourgadget.gadgetbridge.entities.GarminSleepStatsSample; @@ -149,10 +152,12 @@ public class FitImporter { private final List trainingLoadAcuteSamples = new ArrayList<>(); private final List trainingLoadChronicSamples = new ArrayList<>(); private final Map unknownRecords = new HashMap<>(); + @Nullable private FitSleepDataInfo fitSleepDataInfo = null; private final List fitSleepDataRawSamples = new ArrayList<>(); private final List sleepRestlessMomentsSamples = new ArrayList<>(); private final List batterySamples = new ArrayList<>(); + @Nullable private FitFileId fileId = null; private final List genericMetricSamples = new ArrayList<>(); @@ -167,7 +172,7 @@ public class FitImporter { /** * @noinspection StatementWithEmptyBody */ - public void importFile(final File file, boolean isReprocessing) throws IOException, FitParseException { + public void importFile(@NonNull final File file, final boolean isReprocessing) throws IOException, FitParseException { LOG.debug("Parsing {}", file.getAbsolutePath()); reset(); @@ -228,22 +233,22 @@ public class FitImporter { sample.setCount(fitSleepRestlessMoments.getRestlessMomentsCount()); sleepRestlessMomentsSamples.add(sample); } - } else if (record instanceof FitSleepStats) { - final Integer score = ((FitSleepStats) record).getOverallSleepScore(); + } else if (record instanceof FitSleepStats fitSleepStats) { + final Integer score = fitSleepStats.getOverallSleepScore(); if (score == null) { continue; } - LOG.trace("Sleep stats at {}: {}", ts, record); + LOG.trace("Sleep stats at {}: {}", ts, fitSleepStats); final GarminSleepStatsSample sample = new GarminSleepStatsSample(); sample.setTimestamp(ts * 1000L); sample.setSleepScore(score); sleepStatsSamples.add(sample); - } else if (record instanceof FitSleepStage) { - final FieldDefinitionSleepStage.SleepStage stage = ((FitSleepStage) record).getSleepStage(); + } else if (record instanceof FitSleepStage fitSleepStage) { + final FieldDefinitionSleepStage.SleepStage stage = fitSleepStage.getSleepStage(); if (stage == null) { continue; } - LOG.trace("Sleep stage at {}: {}", ts, record); + LOG.trace("Sleep stage at {}: {}", ts, fitSleepStage); final GarminSleepStageSample sample = new GarminSleepStageSample(); sample.setTimestamp(ts * 1000L); sample.setStage(stage.getId()); @@ -262,7 +267,7 @@ public class FitImporter { LOG.trace( "Monitoring at {}: {}", SDF.format(new Date(currentMonitoringTimestamp * 1000L)), - record + monitoringRecord ); if (!activitySamplesPerTimestamp.containsKey(currentMonitoringTimestamp)) { activitySamplesPerTimestamp.put(currentMonitoringTimestamp, new ArrayList<>()); @@ -290,8 +295,8 @@ public class FitImporter { } } spo2samples.add(sample); - } else if (record instanceof FitRespirationRate) { - final Float respiratoryRate = ((FitRespirationRate) record).getRespirationRate(); + } else if (record instanceof FitRespirationRate fitRespirationRate) { + final Float respiratoryRate = fitRespirationRate.getRespirationRate(); if (respiratoryRate == null || respiratoryRate <= 0) { continue; } @@ -331,7 +336,7 @@ public class FitImporter { } else if (record instanceof FitUserProfile) { // handled in workout parser } else if (record instanceof FitHrvSummary hrvSummary) { - LOG.trace("HRV summary at {}: {}", ts, record); + LOG.trace("HRV summary at {}: {}", ts, hrvSummary); final GarminHrvSummarySample sample = new GarminHrvSummarySample(); sample.setTimestamp(ts * 1000L); if (hrvSummary.getWeeklyAverage() != null) { @@ -371,13 +376,13 @@ public class FitImporter { if (monitoringInfo.getRestingMetabolicRate() == null) { continue; } - LOG.trace("Monitoring info at {}: {}", ts, record); + LOG.trace("Monitoring info at {}: {}", ts, monitoringInfo); final GarminRestingMetabolicRateSample sample = new GarminRestingMetabolicRateSample(); sample.setTimestamp(ts * 1000L); sample.setRestingMetabolicRate(monitoringInfo.getRestingMetabolicRate()); restingMetabolicRateSamples.add(sample); } else if (record instanceof FitTrainingLoad trainingLoad) { - LOG.trace("Training load at {}: {}", ts, record); + LOG.trace("Training load at {}: {}", ts, trainingLoad); if (trainingLoad.getTrainingLoadAcute() != null) { final GenericTrainingLoadAcuteSample sample = new GenericTrainingLoadAcuteSample(); sample.setTimestamp(ts * 1000L); @@ -407,7 +412,7 @@ public class FitImporter { restingHrSamples.add(sample); } else if (record instanceof FitDeviceStatus deviceStatus) { Integer level = deviceStatus.getBatteryLevel(); - if (ts != null && level != null){ + if (ts != null && level != null) { BatteryLevel batteryLevel = new BatteryLevel(); batteryLevel.setTimestamp(ts.intValue()); batteryLevel.setBatteryIndex(0); @@ -494,14 +499,14 @@ public class FitImporter { sample.setMetric(MetricSample.Metric.GARMIN_RUNNING_LACTATE_THRESHOLD_POWER, ltp, hr); genericMetricSamples.add(sample); } - }else if(record instanceof FitMaxMetData fitMaxMetData){ + } else if (record instanceof FitMaxMetData fitMaxMetData) { final Float rawVo2Max = fitMaxMetData.getVo2Max(); final Integer rawMaxMetCategory = fitMaxMetData.getMaxMetCategory(); final Double vo2Max = (rawVo2Max == null) ? null : rawVo2Max.doubleValue(); final Long maxMetCategory = (rawMaxMetCategory == null) ? null : rawMaxMetCategory.longValue(); - if((vo2Max != null && vo2Max > 0) || (maxMetCategory != null && maxMetCategory > 0)){ + if ((vo2Max != null && vo2Max > 0) || (maxMetCategory != null && maxMetCategory > 0)) { final GenericMetricSample sample = new GenericMetricSample(); sample.setTimestamp(ts); sample.setMetric(MetricSample.Metric.GARMIN_MET_MAX_VO2, vo2Max, maxMetCategory); @@ -751,9 +756,9 @@ public class FitImporter { if (prevTs > 0 && ts - prevTs > 60) { // Fill gaps between samples LOG.debug( - "Filling gap between {} and {}", - SDF.format(new Date(prevTs * 1000L)), - SDF.format(new Date(ts * 1000L)) + "Filling gap between {} and {}", + SDF.format(new Date(prevTs * 1000L)), + SDF.format(new Date(ts * 1000L)) ); for (int i = prevTs + 60; i < ts; i += 60) { final GarminActivitySample sample = new GarminActivitySample();