Bangle.js: Add ActivityTrackProvider

This commit is contained in:
José Rebelo
2026-03-21 21:55:04 +00:00
parent 4b1abace72
commit 9ddb4895df
3 changed files with 51 additions and 21 deletions
@@ -53,6 +53,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryParser;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityTrackProvider;
import nodomain.freeyourgadget.gadgetbridge.model.BatteryConfig;
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.banglejs.BangleJSDeviceSupport;
@@ -108,7 +109,13 @@ public class BangleJSCoordinator extends AbstractBLEDeviceCoordinator {
@Nullable
@Override
public ActivitySummaryParser getActivitySummaryParser(final GBDevice device, final Context context) {
return new BangleJSWorkoutParser(context);
return new BangleJSWorkoutParser();
}
@Nullable
@Override
public ActivityTrackProvider getActivityTrackProvider(@NonNull final GBDevice device, @NonNull final Context context) {
return new BangleJSWorkoutParser();
}
@Override
@@ -9,7 +9,6 @@ import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.HR_AVG;
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.HR_MAX;
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.HR_MIN;
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.INTERNAL_HAS_GPS;
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.SPEED_AVG;
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.SPEED_MAX;
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.SPEED_MIN;
@@ -24,31 +23,31 @@ import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.UNIT_SPM;
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.UNIT_STEPS;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityPoint;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryData;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryParser;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityTrack;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityTrackProvider;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.model.GPSCoordinate;
import nodomain.freeyourgadget.gadgetbridge.model.GpxActivityTrackProvider;
import nodomain.freeyourgadget.gadgetbridge.util.Accumulator;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
public class BangleJSWorkoutParser implements ActivitySummaryParser {
public class BangleJSWorkoutParser implements ActivitySummaryParser, ActivityTrackProvider {
private static final Logger LOG = LoggerFactory.getLogger(BangleJSWorkoutParser.class);
private final Context mContext;
public BangleJSWorkoutParser(final Context context) {
this.mContext = context;
}
@Override
public BaseActivitySummary parseBinaryData(final BaseActivitySummary summary, final boolean forDetails) {
if (!forDetails) {
@@ -56,22 +55,47 @@ public class BangleJSWorkoutParser implements ActivitySummaryParser {
return summary;
}
final List<BangleJSActivityPoint> points = getBangleJSActivityPoints(summary);
if (points == null) return summary;
summary.setSummaryData(dataFromPoints(points).toString());
return summary;
}
@Nullable
@Override
public ActivityTrack getActivityTrack(@NonNull final BaseActivitySummary summary) {
final List<BangleJSActivityPoint> points = getBangleJSActivityPoints(summary);
if (points == null) {
// Fallback to gpx, in case the csv was deleted
return new GpxActivityTrackProvider().getActivityTrack(summary);
}
final List<ActivityPoint> activityPoints = points.stream().map(BangleJSActivityPoint::toActivityPoint).collect(Collectors.toList());
final ActivityTrack activityTrack = new ActivityTrack();
activityTrack.setName(summary.getName());
activityTrack.addTrackPoints(activityPoints);
return activityTrack;
}
@Nullable
private static List<BangleJSActivityPoint> getBangleJSActivityPoints(@NonNull final BaseActivitySummary summary) {
if (summary.getRawDetailsPath() == null) {
return summary;
LOG.debug("Raw details path for summary {} is null", summary.getId());
return null;
}
final File inputFile = FileUtils.tryFixPath(new File(summary.getRawDetailsPath()));
if (inputFile == null) {
return summary;
LOG.debug("Raw details file not found: {}", summary.getRawDetailsPath());
return null;
}
final List<BangleJSActivityPoint> points = BangleJSActivityPoint.fromCsv(inputFile);
if (points == null) {
return summary;
}
LOG.debug("Loading bangle activity points from {}", inputFile);
summary.setSummaryData(dataFromPoints(points).toString());
return summary;
return BangleJSActivityPoint.fromCsv(inputFile);
}
public static ActivitySummaryData dataFromPoints(final List<BangleJSActivityPoint> points) {
@@ -167,7 +191,7 @@ public class BangleJSWorkoutParser implements ActivitySummaryParser {
// TODO: Does Bangle.js report laps in recorder logs?
summaryData.add(INTERNAL_HAS_GPS, String.valueOf(hasGps));
summaryData.setHasGps(hasGps);
return summaryData;
}
@@ -3,7 +3,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.banglejs;
import static java.lang.Integer.parseInt;
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.HR_AVG;
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.INTERNAL_HAS_GPS;
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.SPEED_AVG;
import android.content.Context;
@@ -199,7 +198,7 @@ class BangleJSActivityTrack {
} catch (Exception ex) {
GB.toast(context, "Error setting user for activity track.", Toast.LENGTH_LONG, GB.ERROR, ex);
}
boolean hasGPXReading = summaryData.has(INTERNAL_HAS_GPS);
boolean hasGPXReading = summaryData.hasGps();
boolean hasHRMReading = summaryData.has(HR_AVG);
for (final BangleJSActivityPoint banglePoint : banglePoints) {
track.addTrackPoint(banglePoint.toActivityPoint());