diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/HeartRateUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/HeartRateUtils.java index a2f3b0734..b4aaf949f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/HeartRateUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/HeartRateUtils.java @@ -16,9 +16,14 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.activities; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; + public class HeartRateUtils { public static final int MAX_HEART_RATE_VALUE = 250; - public static final int MIN_HEART_RATE_VALUE = 0; + public static final int MIN_HEART_RATE_VALUE = 10; + /** * The maxiumum gap between two hr measurements in which * we interpolate between the measurements. Otherwise, two @@ -28,7 +33,37 @@ public class HeartRateUtils { */ public static final int MAX_HR_MEASUREMENTS_GAP_MINUTES = 10; - public static boolean isValidHeartRateValue(int value) { - return value > HeartRateUtils.MIN_HEART_RATE_VALUE && value < HeartRateUtils.MAX_HEART_RATE_VALUE; + private int maxHeartRateValue; + private int minHeartRateValue; + + private static final HeartRateUtils instance = new HeartRateUtils(); + + public static HeartRateUtils getInstance() { + return instance; + } + + /** + * Singleton - to access this class use the static #getInstance() + */ + private HeartRateUtils() { + updateCachedHeartRatePreferences(); + } + + public void updateCachedHeartRatePreferences(){ + Prefs prefs = GBApplication.getPrefs(); + maxHeartRateValue = prefs.getInt(GBPrefs.CHART_MAX_HEART_RATE, MAX_HEART_RATE_VALUE); + minHeartRateValue = prefs.getInt(GBPrefs.CHART_MIN_HEART_RATE, MIN_HEART_RATE_VALUE); + } + + public int getMaxHeartRate(){ + return maxHeartRateValue; + } + + public int getMinHeartRate(){ + return minHeartRateValue; + } + + public boolean isValidHeartRateValue(int value) { + return value >= getMinHeartRate() && value <= getMaxHeartRate(); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractChartFragment.java index e9fa8f020..b1ae9cc48 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractChartFragment.java @@ -70,8 +70,6 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; -import static nodomain.freeyourgadget.gadgetbridge.activities.HeartRateUtils.isValidHeartRateValue; - /** * A base class fragment to be used with ChartsActivity. The fragment can supply * a title to be displayed in the activity by returning non-null in #getTitle() @@ -443,6 +441,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment { List heartrateEntries = hr ? new ArrayList(numEntries) : null; List colors = new ArrayList<>(numEntries); // this is kinda inefficient... int lastHrSampleIndex = -1; + HeartRateUtils heartRateUtilsInstance = HeartRateUtils.getInstance(); for (int i = 0; i < numEntries; i++) { ActivitySample sample = samples.get(i); @@ -512,7 +511,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment { } activityEntries.add(createLineEntry(value, ts)); } - if (hr && sample.getKind() != ActivityKind.TYPE_NOT_WORN && HeartRateUtils.isValidHeartRateValue(sample.getHeartRate())) { + if (hr && sample.getKind() != ActivityKind.TYPE_NOT_WORN && heartRateUtilsInstance.isValidHeartRateValue(sample.getHeartRate())) { if (lastHrSampleIndex > -1 && ts - lastHrSampleIndex > 1800*HeartRateUtils.MAX_HR_MEASUREMENTS_GAP_MINUTES) { heartrateEntries.add(createLineEntry(0, lastHrSampleIndex + 1)); heartrateEntries.add(createLineEntry(0, ts - 1)); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivitySleepChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivitySleepChartFragment.java index f2541b64a..c1579891d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivitySleepChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivitySleepChartFragment.java @@ -104,8 +104,8 @@ public class ActivitySleepChartFragment extends AbstractChartFragment { yAxisRight.setDrawLabels(true); yAxisRight.setDrawTopYLabelEntry(true); yAxisRight.setTextColor(CHART_TEXT_COLOR); - yAxisRight.setAxisMaximum(HeartRateUtils.MAX_HEART_RATE_VALUE); - yAxisRight.setAxisMinimum(HeartRateUtils.MIN_HEART_RATE_VALUE); + yAxisRight.setAxisMaximum(HeartRateUtils.getInstance().getMaxHeartRate()); + yAxisRight.setAxisMinimum(HeartRateUtils.getInstance().getMinHeartRate()); // refresh immediately instead of use refreshIfVisible(), for perceived performance refresh(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/LiveActivityFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/LiveActivityFragment.java index 53c7563fd..2331a5a22 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/LiveActivityFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/LiveActivityFragment.java @@ -168,7 +168,7 @@ public class LiveActivityFragment extends AbstractChartFragment { private void addSample(ActivitySample sample) { int heartRate = sample.getHeartRate(); int timestamp = tsTranslation.shorten(sample.getTimestamp()); - if (HeartRateUtils.isValidHeartRateValue(heartRate)) { + if (HeartRateUtils.getInstance().isValidHeartRateValue(heartRate)) { setCurrentHeartRate(heartRate, timestamp); } int steps = sample.getSteps(); @@ -470,8 +470,8 @@ public class LiveActivityFragment extends AbstractChartFragment { yAxisRight.setDrawLabels(true); yAxisRight.setDrawTopYLabelEntry(false); yAxisRight.setTextColor(CHART_TEXT_COLOR); - yAxisRight.setAxisMaximum(HeartRateUtils.MAX_HEART_RATE_VALUE); - yAxisRight.setAxisMinimum(HeartRateUtils.MIN_HEART_RATE_VALUE); + yAxisRight.setAxisMaximum(HeartRateUtils.getInstance().getMaxHeartRate()); + yAxisRight.setAxisMinimum(HeartRateUtils.getInstance().getMinHeartRate()); mHistorySet = new LineDataSet(new ArrayList(), getString(R.string.live_activity_steps_history)); mHistorySet.setAxisDependency(YAxis.AxisDependency.LEFT); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepChartFragment.java index c9b7cd7b2..9cd13a2d1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepChartFragment.java @@ -233,8 +233,8 @@ public class SleepChartFragment extends AbstractChartFragment { yAxisRight.setDrawLabels(true); yAxisRight.setDrawTopYLabelEntry(true); yAxisRight.setTextColor(CHART_TEXT_COLOR); - yAxisRight.setAxisMaxValue(HeartRateUtils.MAX_HEART_RATE_VALUE); - yAxisRight.setAxisMinValue(HeartRateUtils.MIN_HEART_RATE_VALUE); + yAxisRight.setAxisMaxValue(HeartRateUtils.getInstance().getMaxHeartRate()); + yAxisRight.setAxisMinValue(HeartRateUtils.getInstance().getMinHeartRate()); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java index 2773f9208..ab8b64914 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/export/GPXExporter.java @@ -151,7 +151,7 @@ public class GPXExporter implements ActivityTrackExporter { } int hr = point.getHeartRate(); - if (!HeartRateUtils.isValidHeartRateValue(hr)) { + if (!HeartRateUtils.getInstance().isValidHeartRateValue(hr)) { if (!includeHeartRateOfNearestSample) { return; } @@ -162,7 +162,7 @@ public class GPXExporter implements ActivityTrackExporter { } hr = closestPointItem.getHeartRate(); - if (!HeartRateUtils.isValidHeartRateValue(hr)) { + if (!HeartRateUtils.getInstance().isValidHeartRateValue(hr)) { return; } } @@ -177,11 +177,12 @@ public class GPXExporter implements ActivityTrackExporter { private @Nullable ActivityPoint findClosestSensibleActivityPoint(Date time, List trackPoints) { ActivityPoint closestPointItem = null; + HeartRateUtils heartRateUtilsInstance = HeartRateUtils.getInstance(); long lowestDifference = 60 * 2 * 1000; // minimum distance is 2min for (ActivityPoint pointItem : trackPoints) { int hrItem = pointItem.getHeartRate(); - if (HeartRateUtils.isValidHeartRateValue(hrItem)) { + if (heartRateUtilsInstance.isValidHeartRateValue(hrItem)) { Date timeItem = pointItem.getTime(); if (timeItem.after(time) || timeItem.equals(time)) { break; // we assume that the given trackPoints are sorted in time ascending order (oldest first) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index 2c183defb..b96b663c1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -47,6 +47,7 @@ import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.activities.HeartRateUtils; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmClockReceiver; import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmReceiver; @@ -784,6 +785,9 @@ public class DeviceCommunicationService extends Service implements SharedPrefere mDeviceSupport.setAutoReconnect(autoReconnect); } } + if (GBPrefs.CHART_MAX_HEART_RATE.equals(key) || GBPrefs.CHART_MIN_HEART_RATE.equals(key)) { + HeartRateUtils.getInstance().updateCachedHeartRatePreferences(); + } } protected boolean hasPrefs() { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java index 1bd889bb1..c075563f4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java @@ -38,6 +38,9 @@ public class GBPrefs { public static final String USER_NAME_DEFAULT = "gadgetbridge-user"; private static final String USER_BIRTHDAY = ""; + public static final String CHART_MAX_HEART_RATE = "chart_max_heart_rate"; + public static final String CHART_MIN_HEART_RATE = "chart_min_heart_rate"; + private final Prefs mPrefs; public GBPrefs(Prefs prefs) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 32df5a596..7f0f1b45f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -469,6 +469,10 @@ Height in cm Weight in kg + Chart settings + Max heart rate + Min heart rate + Authenticating Authentication required diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index d4ada4d19..49dcc296c 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -101,6 +101,24 @@ android:maxLength="2" android:title="@string/activity_prefs_sleep_duration" /> + + + + + +