wip: refactor charts to get hr from a separate file

This commit is contained in:
José Rebelo 2024-01-07 20:55:36 +00:00
parent ab894ae433
commit 8c91c53bd5
4 changed files with 178 additions and 8 deletions

View File

@ -37,7 +37,11 @@ import com.github.mikephil.charting.data.LineData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.R;
@ -47,8 +51,14 @@ import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsHost;
import nodomain.freeyourgadget.gadgetbridge.activities.charts.DefaultChartsData;
import nodomain.freeyourgadget.gadgetbridge.database.DBAccess;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.util.gpx.GpxParseException;
import nodomain.freeyourgadget.gadgetbridge.util.gpx.GpxParser;
import nodomain.freeyourgadget.gadgetbridge.util.gpx.model.GpxFile;
import nodomain.freeyourgadget.gadgetbridge.util.gpx.model.GpxTrackPoint;
public class ActivitySummariesChartFragment extends AbstractActivityChartFragment<ChartsData> {
@ -59,18 +69,60 @@ public class ActivitySummariesChartFragment extends AbstractActivityChartFragmen
private int endTime;
private GBDevice gbDevice;
private View view;
private File gpxFile;
public void setDateAndGetData(GBDevice gbDevice, long startTime, long endTime) {
this.startTime = (int) startTime;
this.endTime = (int) endTime;
this.gbDevice = gbDevice;
this.gpxFile = null;
if (this.view != null) {
createLocalRefreshTask("Visualizing data", getActivity()).execute();
}
}
public void setDateAndGetData(GBDevice gbDevice, File gpxFile) {
this.gbDevice = gbDevice;
this.gpxFile = gpxFile;
this.startTime = 0;
this.endTime = 0;
if (this.view != null) {
createLocalRefreshTask("Visualizing data", getActivity()).execute();
}
}
protected RefreshTask createLocalRefreshTask(String task, Context context) {
return new RefreshTask(task, context);
if (gpxFile != null) {
return new RefreshTask(task, context, (dbHandler) -> {
final GpxFile gpx;
try (FileInputStream inputStream = new FileInputStream(gpxFile)) {
final GpxParser gpxParser = new GpxParser(inputStream);
gpx = gpxParser.getGpxFile();
} catch (final IOException e) {
LOG.error("Failed to open {}", gpxFile, e);
// fallback to activity samples
return getAllSamples(dbHandler, gbDevice, startTime, endTime);
} catch (final GpxParseException e) {
LOG.error("Failed to parse gpx file", e);
// fallback to activity samples
return getAllSamples(dbHandler, gbDevice, startTime, endTime);
}
final List<GpxActivitySample> ret = new ArrayList<>(gpx.getPoints().size());
for (final GpxTrackPoint point : gpx.getPoints()) {
ret.add(new GpxActivitySample(
(int) (point.getTime().getTime() / 1000L),
point.getHeartRate()
));
}
return ret;
});
} else {
return new RefreshTask(task, context, (dbHandler) -> getAllSamples(dbHandler, gbDevice, startTime, endTime));
}
}
@Override
@ -135,6 +187,8 @@ public class ActivitySummariesChartFragment extends AbstractActivityChartFragmen
@Override
protected List<? extends ActivitySample> getSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
LOG.warn("This should not need to be called...");
// FIXME: This fragment should be refactored, this is not even used
return getAllSamples(db, device, tsFrom, tsTo);
}
@ -178,16 +232,18 @@ public class ActivitySummariesChartFragment extends AbstractActivityChartFragmen
}
public class RefreshTask extends DBAccess {
private final ActivitySampleGetter getter;
public RefreshTask(String task, Context context) {
public RefreshTask(final String task, final Context context, final ActivitySampleGetter getter) {
super(task, context);
this.getter = getter;
}
@Override
protected void doInBackground(DBHandler handler) {
List<? extends ActivitySample> samples = getAllSamples(handler, gbDevice, startTime, endTime);
List<? extends ActivitySample> samples = getter.getSamples(handler);
DefaultChartsData dcd = null;
DefaultChartsData<LineData> dcd = null;
try {
dcd = refresh(gbDevice, samples);
} catch (Exception e) {
@ -205,4 +261,64 @@ public class ActivitySummariesChartFragment extends AbstractActivityChartFragmen
mChart.invalidate();
}
}
public interface ActivitySampleGetter {
List<? extends ActivitySample> getSamples(DBHandler handler);
}
private static class GpxActivitySample implements ActivitySample {
private final int timestamp;
private final int hr;
public GpxActivitySample(final int timestamp, final int hr) {
this.timestamp = timestamp;
this.hr = hr;
}
@Override
public SampleProvider getProvider() {
return null;
}
@Override
public int getRawKind() {
return ActivityKind.TYPE_ACTIVITY;
}
@Override
public int getKind() {
return ActivityKind.TYPE_ACTIVITY;
}
@Override
public int getRawIntensity() {
return 0;
}
@Override
public float getIntensity() {
return 0;
}
@Override
public int getSteps() {
return 0;
}
@Override
public int getHeartRate() {
return hr;
}
@Override
public void setHeartRate(final int value) {
}
@Override
public int getTimestamp() {
return timestamp;
}
}
}

View File

@ -182,11 +182,13 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
currentItem = newItem;
makeSummaryHeader(newItem);
makeSummaryContent(newItem);
activitySummariesChartFragment.setDateAndGetData(getGBDevice(currentItem.getDevice()), currentItem.getStartTime().getTime() / 1000, currentItem.getEndTime().getTime() / 1000);
if (get_gpx_file() != null) {
final File gpxFile = get_gpx_file();
if (gpxFile != null) {
activitySummariesChartFragment.setDateAndGetData(getGBDevice(currentItem.getDevice()), gpxFile);
showCanvas();
activitySummariesGpsFragment.set_data(get_gpx_file());
activitySummariesGpsFragment.set_data(gpxFile);
} else {
activitySummariesChartFragment.setDateAndGetData(getGBDevice(currentItem.getDevice()), currentItem.getStartTime().getTime() / 1000, currentItem.getEndTime().getTime() / 1000);
hideCanvas();
}

View File

@ -168,6 +168,12 @@ public class GpxParser {
case "time":
trackPointBuilder.withTime(parseTime());
continue;
case "extensions":
final int hr = parseExtensions();
if (hr >= 0) {
trackPointBuilder.withHeartRate(hr);
}
continue;
}
}
@ -177,6 +183,36 @@ public class GpxParser {
return trackPointBuilder.build();
}
private int parseExtensions() throws Exception {
while (eventType != XmlPullParser.END_TAG || !parser.getName().equals("extensions")) {
if (parser.getEventType() == XmlPullParser.START_TAG) {
switch (parser.getName()) {
case "gpxtpx:TrackPointExtension":
return parseTrackPointExtension();
}
}
eventType = parser.next();
}
return -1;
}
private int parseTrackPointExtension() throws Exception {
while (eventType != XmlPullParser.END_TAG || !parser.getName().equals("gpxtpx:TrackPointExtension")) {
if (parser.getEventType() == XmlPullParser.START_TAG) {
switch (parser.getName()) {
case "gpxtpx:hr":
return Integer.parseInt(parseStringContent("gpxtpx:hr"));
}
}
eventType = parser.next();
}
return -1;
}
private GpxWaypoint parseWaypoint() throws Exception {
final GpxWaypoint.Builder waypointBuilder = new GpxWaypoint.Builder();

View File

@ -23,16 +23,26 @@ import nodomain.freeyourgadget.gadgetbridge.model.GPSCoordinate;
public class GpxTrackPoint extends GPSCoordinate {
private final Date time;
private final int heartRate;
public GpxTrackPoint(final double longitude, final double latitude, final double altitude, final Date time) {
public GpxTrackPoint(final double longitude, final double latitude, final double altitude, final Date time, final int heartRate) {
super(longitude, latitude, altitude);
this.time = time;
this.heartRate = heartRate;
}
public GpxTrackPoint(final double longitude, final double latitude, final double altitude, final Date time) {
this(longitude, latitude, altitude, time, -1);
}
public Date getTime() {
return time;
}
public int getHeartRate() {
return heartRate;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@ -52,6 +62,7 @@ public class GpxTrackPoint extends GPSCoordinate {
private double latitude;
private double altitude;
private Date time;
private int heartRate;
public Builder withLongitude(final double longitude) {
this.longitude = longitude;
@ -73,6 +84,11 @@ public class GpxTrackPoint extends GPSCoordinate {
return this;
}
public Builder withHeartRate(final int heartRate) {
this.heartRate = heartRate;
return this;
}
public GpxTrackPoint build() {
return new GpxTrackPoint(longitude, latitude, altitude, time);
}