mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-09-27 16:56:57 +02:00
wip: refactor charts to get hr from a separate file
This commit is contained in:
parent
ab894ae433
commit
8c91c53bd5
@ -37,7 +37,11 @@ import com.github.mikephil.charting.data.LineData;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
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.activities.charts.DefaultChartsData;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBAccess;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBAccess;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
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> {
|
public class ActivitySummariesChartFragment extends AbstractActivityChartFragment<ChartsData> {
|
||||||
@ -59,18 +69,60 @@ public class ActivitySummariesChartFragment extends AbstractActivityChartFragmen
|
|||||||
private int endTime;
|
private int endTime;
|
||||||
private GBDevice gbDevice;
|
private GBDevice gbDevice;
|
||||||
private View view;
|
private View view;
|
||||||
|
private File gpxFile;
|
||||||
|
|
||||||
public void setDateAndGetData(GBDevice gbDevice, long startTime, long endTime) {
|
public void setDateAndGetData(GBDevice gbDevice, long startTime, long endTime) {
|
||||||
this.startTime = (int) startTime;
|
this.startTime = (int) startTime;
|
||||||
this.endTime = (int) endTime;
|
this.endTime = (int) endTime;
|
||||||
this.gbDevice = gbDevice;
|
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) {
|
if (this.view != null) {
|
||||||
createLocalRefreshTask("Visualizing data", getActivity()).execute();
|
createLocalRefreshTask("Visualizing data", getActivity()).execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RefreshTask createLocalRefreshTask(String task, Context context) {
|
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
|
@Override
|
||||||
@ -135,6 +187,8 @@ public class ActivitySummariesChartFragment extends AbstractActivityChartFragmen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<? extends ActivitySample> getSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
|
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);
|
return getAllSamples(db, device, tsFrom, tsTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,16 +232,18 @@ public class ActivitySummariesChartFragment extends AbstractActivityChartFragmen
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class RefreshTask extends DBAccess {
|
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);
|
super(task, context);
|
||||||
|
this.getter = getter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doInBackground(DBHandler handler) {
|
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 {
|
try {
|
||||||
dcd = refresh(gbDevice, samples);
|
dcd = refresh(gbDevice, samples);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -205,4 +261,64 @@ public class ActivitySummariesChartFragment extends AbstractActivityChartFragmen
|
|||||||
mChart.invalidate();
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,11 +182,13 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
|
|||||||
currentItem = newItem;
|
currentItem = newItem;
|
||||||
makeSummaryHeader(newItem);
|
makeSummaryHeader(newItem);
|
||||||
makeSummaryContent(newItem);
|
makeSummaryContent(newItem);
|
||||||
activitySummariesChartFragment.setDateAndGetData(getGBDevice(currentItem.getDevice()), currentItem.getStartTime().getTime() / 1000, currentItem.getEndTime().getTime() / 1000);
|
final File gpxFile = get_gpx_file();
|
||||||
if (get_gpx_file() != null) {
|
if (gpxFile != null) {
|
||||||
|
activitySummariesChartFragment.setDateAndGetData(getGBDevice(currentItem.getDevice()), gpxFile);
|
||||||
showCanvas();
|
showCanvas();
|
||||||
activitySummariesGpsFragment.set_data(get_gpx_file());
|
activitySummariesGpsFragment.set_data(gpxFile);
|
||||||
} else {
|
} else {
|
||||||
|
activitySummariesChartFragment.setDateAndGetData(getGBDevice(currentItem.getDevice()), currentItem.getStartTime().getTime() / 1000, currentItem.getEndTime().getTime() / 1000);
|
||||||
hideCanvas();
|
hideCanvas();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,6 +168,12 @@ public class GpxParser {
|
|||||||
case "time":
|
case "time":
|
||||||
trackPointBuilder.withTime(parseTime());
|
trackPointBuilder.withTime(parseTime());
|
||||||
continue;
|
continue;
|
||||||
|
case "extensions":
|
||||||
|
final int hr = parseExtensions();
|
||||||
|
if (hr >= 0) {
|
||||||
|
trackPointBuilder.withHeartRate(hr);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,6 +183,36 @@ public class GpxParser {
|
|||||||
return trackPointBuilder.build();
|
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 {
|
private GpxWaypoint parseWaypoint() throws Exception {
|
||||||
final GpxWaypoint.Builder waypointBuilder = new GpxWaypoint.Builder();
|
final GpxWaypoint.Builder waypointBuilder = new GpxWaypoint.Builder();
|
||||||
|
|
||||||
|
@ -23,16 +23,26 @@ import nodomain.freeyourgadget.gadgetbridge.model.GPSCoordinate;
|
|||||||
|
|
||||||
public class GpxTrackPoint extends GPSCoordinate {
|
public class GpxTrackPoint extends GPSCoordinate {
|
||||||
private final Date time;
|
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);
|
super(longitude, latitude, altitude);
|
||||||
this.time = time;
|
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() {
|
public Date getTime() {
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getHeartRate() {
|
||||||
|
return heartRate;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
@ -52,6 +62,7 @@ public class GpxTrackPoint extends GPSCoordinate {
|
|||||||
private double latitude;
|
private double latitude;
|
||||||
private double altitude;
|
private double altitude;
|
||||||
private Date time;
|
private Date time;
|
||||||
|
private int heartRate;
|
||||||
|
|
||||||
public Builder withLongitude(final double longitude) {
|
public Builder withLongitude(final double longitude) {
|
||||||
this.longitude = longitude;
|
this.longitude = longitude;
|
||||||
@ -73,6 +84,11 @@ public class GpxTrackPoint extends GPSCoordinate {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder withHeartRate(final int heartRate) {
|
||||||
|
this.heartRate = heartRate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public GpxTrackPoint build() {
|
public GpxTrackPoint build() {
|
||||||
return new GpxTrackPoint(longitude, latitude, altitude, time);
|
return new GpxTrackPoint(longitude, latitude, altitude, time);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user