diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/Huami2021Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/Huami2021Support.java index 2ad23da89..8d8a8018f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/Huami2021Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/Huami2021Support.java @@ -390,7 +390,7 @@ public abstract class Huami2021Support extends HuamiSupport { new FetchActivityOperation(this).perform(); break; case RecordedDataTypes.TYPE_GPS_TRACKS: - new FetchSportsSummaryOperation(this).perform(); + new FetchSportsSummaryOperation(this, 1).perform(); break; case RecordedDataTypes.TYPE_DEBUGLOGS: new HuamiFetchDebugLogsOperation(this).perform(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java index e670d6371..858e524c1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/amazfitbip/AmazfitBipSupport.java @@ -87,7 +87,7 @@ public class AmazfitBipSupport extends HuamiSupport { if (dataTypes == RecordedDataTypes.TYPE_ACTIVITY) { new FetchActivityOperation(this).perform(); } else if (dataTypes == RecordedDataTypes.TYPE_GPS_TRACKS) { - new FetchSportsSummaryOperation(this).perform(); + new FetchSportsSummaryOperation(this, 1).perform(); } else if (dataTypes == RecordedDataTypes.TYPE_DEBUGLOGS) { new HuamiFetchDebugLogsOperation(this).perform(); } else { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsDetailsOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsDetailsOperation.java index c681cde8f..ea8797b21 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsDetailsOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsDetailsOperation.java @@ -17,6 +17,7 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations; +import android.text.format.DateUtils; import android.widget.Toast; import org.slf4j.Logger; @@ -29,6 +30,7 @@ import java.io.IOException; import java.util.GregorianCalendar; import androidx.annotation.NonNull; + import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.Logging; import nodomain.freeyourgadget.gadgetbridge.R; @@ -64,12 +66,14 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation { FetchSportsDetailsOperation(@NonNull BaseActivitySummary summary, @NonNull AbstractHuamiActivityDetailsParser detailsParser, @NonNull HuamiSupport support, - @NonNull String lastSyncTimeKey) { + @NonNull String lastSyncTimeKey, + int fetchCount) { super(support); setName("fetching sport details"); this.summary = summary; this.detailsParser = detailsParser; this.lastSyncTimeKey = lastSyncTimeKey; + this.fetchCount = fetchCount; } @Override @@ -83,15 +87,6 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation { @Override protected boolean handleActivityFetchFinish(boolean success) { LOG.info(getName() + " has finished round " + fetchCount); -// GregorianCalendar lastSyncTimestamp = saveSamples(); -// if (lastSyncTimestamp != null && needsAnotherFetch(lastSyncTimestamp)) { -// try { -// startFetching(); -// return; -// } catch (IOException ex) { -// LOG.error("Error starting another round of fetching activity data", ex); -// } -// } boolean parseSuccess = true; @@ -125,7 +120,7 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation { } final String rawBytesPath = saveRawBytes(); - String fileName = FileUtils.makeValidFileName("gadgetbridge-"+trackType.toLowerCase()+"-" + DateTimeUtils.formatIso8601(summary.getStartTime()) + ".gpx"); + String fileName = FileUtils.makeValidFileName("gadgetbridge-" + trackType.toLowerCase() + "-" + DateTimeUtils.formatIso8601(summary.getStartTime()) + ".gpx"); File targetFile = new File(FileUtils.getExternalFilesDir(), fileName); try { @@ -147,18 +142,47 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation { } } + final boolean superSuccess = super.handleActivityFetchFinish(success); + if (success && parseSuccess) { // Always increment the sync timestamp on success, even if we did not get data GregorianCalendar endTime = BLETypeConversions.createCalendar(); endTime.setTime(summary.getEndTime()); saveLastSyncTimestamp(endTime); + + if (needsAnotherFetch(endTime)) { + FetchSportsSummaryOperation nextOperation = new FetchSportsSummaryOperation(getSupport(), fetchCount); + try { + nextOperation.perform(); + } catch (IOException ex) { + LOG.error("Error starting another round of fetching activity data", ex); + } + } } - final boolean superSuccess = super.handleActivityFetchFinish(success); return superSuccess && parseSuccess; } + private boolean needsAnotherFetch(GregorianCalendar lastSyncTimestamp) { + // We have 2 operations per fetch round: summary + details + if (fetchCount > 10) { + LOG.warn("Already have 5 fetch rounds, not doing another one."); + return false; + } + + if (DateUtils.isToday(lastSyncTimestamp.getTimeInMillis())) { + LOG.info("Hopefully no further fetch needed, last synced timestamp is from today."); + return false; + } + if (lastSyncTimestamp.getTimeInMillis() > System.currentTimeMillis()) { + LOG.warn("Not doing another fetch since last synced timestamp is in the future: {}", DateTimeUtils.formatDateTime(lastSyncTimestamp.getTime())); + return false; + } + LOG.info("Doing another fetch since last sync timestamp is still too old: {}", DateTimeUtils.formatDateTime(lastSyncTimestamp.getTime())); + return true; + } + @Override protected boolean validChecksum(int crc32) { return crc32 == CheckSums.getCRC32(buffer.toByteArray()); @@ -196,7 +220,7 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation { return; } - if ((byte) (lastPacketCounter + 1) == value[0] ) { + if ((byte) (lastPacketCounter + 1) == value[0]) { lastPacketCounter++; bufferActivityData(value); } else { @@ -208,6 +232,7 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation { /** * Buffers the given activity summary data. If the total size is reached, * it is converted to an object and saved in the database. + * * @param value */ @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsSummaryOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsSummaryOperation.java index 54a25fa8f..04fab1c53 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsSummaryOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/FetchSportsSummaryOperation.java @@ -57,9 +57,10 @@ public class FetchSportsSummaryOperation extends AbstractFetchOperation { private static final Logger LOG = LoggerFactory.getLogger(FetchSportsSummaryOperation.class); private ByteArrayOutputStream buffer = new ByteArrayOutputStream(140); - public FetchSportsSummaryOperation(HuamiSupport support) { + public FetchSportsSummaryOperation(HuamiSupport support, int fetchCount) { super(support); setName("fetching sport summaries"); + this.fetchCount = fetchCount; } @Override @@ -73,15 +74,6 @@ public class FetchSportsSummaryOperation extends AbstractFetchOperation { protected boolean handleActivityFetchFinish(boolean success) { LOG.info(getName() + " has finished round " + fetchCount); -// GregorianCalendar lastSyncTimestamp = saveSamples(); -// if (lastSyncTimestamp != null && needsAnotherFetch(lastSyncTimestamp)) { -// try { -// startFetching(); -// return; -// } catch (IOException ex) { -// LOG.error("Error starting another round of fetching activity data", ex); -// } -// } BaseActivitySummary summary = null; final DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(getDevice()); @@ -124,7 +116,7 @@ public class FetchSportsSummaryOperation extends AbstractFetchOperation { if (summary != null) { final AbstractHuamiActivityDetailsParser detailsParser = ((HuamiActivitySummaryParser) summaryParser).getDetailsParser(summary); - FetchSportsDetailsOperation nextOperation = new FetchSportsDetailsOperation(summary, detailsParser, getSupport(), getLastSyncTimeKey()); + FetchSportsDetailsOperation nextOperation = new FetchSportsDetailsOperation(summary, detailsParser, getSupport(), getLastSyncTimeKey(), fetchCount); try { nextOperation.perform(); } catch (IOException ex) {