mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-07-03 11:33:19 +02:00
Some improvements to live activity.
Still rather inaccurate due to missing timing information.
This commit is contained in:
parent
52f3ca5253
commit
aa5749cd40
|
@ -7,6 +7,7 @@ import android.content.IntentFilter;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.FragmentActivity;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -16,6 +17,7 @@ import android.widget.Toast;
|
||||||
|
|
||||||
import com.github.mikephil.charting.charts.BarLineChartBase;
|
import com.github.mikephil.charting.charts.BarLineChartBase;
|
||||||
import com.github.mikephil.charting.charts.Chart;
|
import com.github.mikephil.charting.charts.Chart;
|
||||||
|
import com.github.mikephil.charting.components.LimitLine;
|
||||||
import com.github.mikephil.charting.components.XAxis;
|
import com.github.mikephil.charting.components.XAxis;
|
||||||
import com.github.mikephil.charting.components.YAxis;
|
import com.github.mikephil.charting.components.YAxis;
|
||||||
import com.github.mikephil.charting.data.BarData;
|
import com.github.mikephil.charting.data.BarData;
|
||||||
|
@ -31,6 +33,9 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
@ -42,11 +47,22 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
public class LiveActivityFragment extends AbstractChartFragment {
|
public class LiveActivityFragment extends AbstractChartFragment {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(LiveActivityFragment.class);
|
private static final Logger LOG = LoggerFactory.getLogger(LiveActivityFragment.class);
|
||||||
|
private static final int MAX_STEPS_PER_MINUTE = 300;
|
||||||
|
private static final int MIN_STEPS_PER_MINUTE = 60;
|
||||||
|
private static final int RESET_COUNT = 10; // reset the max steps per minute value every 10s
|
||||||
|
|
||||||
private BarEntry totalStepsEntry;
|
private BarEntry totalStepsEntry;
|
||||||
private BarEntry stepsPerMinuteEntry;
|
private BarEntry stepsPerMinuteEntry;
|
||||||
private BarDataSet mStepsPerMinuteData;
|
private BarDataSet mStepsPerMinuteData;
|
||||||
private BarDataSet mTotalStepsData;
|
private BarDataSet mTotalStepsData;
|
||||||
private LineDataSet mHistorySet;
|
private LineDataSet mHistorySet;
|
||||||
|
private BarLineChartBase mStepsPerMinuteHistoryChart;
|
||||||
|
private CustomBarChart mStepsPerMinuteCurrentChart;
|
||||||
|
private CustomBarChart mTotalStepsChart;
|
||||||
|
|
||||||
|
private Steps mSteps = new Steps();
|
||||||
|
private ScheduledExecutorService pulseScheduler;
|
||||||
|
private int maxStepsResetCounter;
|
||||||
|
|
||||||
private class Steps {
|
private class Steps {
|
||||||
private int initialSteps;
|
private int initialSteps;
|
||||||
|
@ -55,9 +71,15 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
||||||
private long lastTimestamp;
|
private long lastTimestamp;
|
||||||
private int currentStepsPerMinute;
|
private int currentStepsPerMinute;
|
||||||
private int maxStepsPerMinute;
|
private int maxStepsPerMinute;
|
||||||
|
private int lastStepsPerMinute;
|
||||||
|
|
||||||
public int getStepsPerMinute() {
|
public int getStepsPerMinute(boolean reset) {
|
||||||
return currentStepsPerMinute;
|
lastStepsPerMinute = currentStepsPerMinute;
|
||||||
|
int result = currentStepsPerMinute;
|
||||||
|
if (reset) {
|
||||||
|
currentStepsPerMinute = 0;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTotalSteps() {
|
public int getTotalSteps() {
|
||||||
|
@ -84,7 +106,10 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
||||||
int stepsDelta = newSteps - steps;
|
int stepsDelta = newSteps - steps;
|
||||||
long timeDelta = timestamp - lastTimestamp;
|
long timeDelta = timestamp - lastTimestamp;
|
||||||
currentStepsPerMinute = calculateStepsPerMinute(stepsDelta, timeDelta);
|
currentStepsPerMinute = calculateStepsPerMinute(stepsDelta, timeDelta);
|
||||||
maxStepsPerMinute = Math.max(maxStepsPerMinute, currentStepsPerMinute);
|
if (currentStepsPerMinute > maxStepsPerMinute) {
|
||||||
|
maxStepsPerMinute = currentStepsPerMinute;
|
||||||
|
maxStepsResetCounter = 0;
|
||||||
|
}
|
||||||
steps = newSteps;
|
steps = newSteps;
|
||||||
lastTimestamp = timestamp;
|
lastTimestamp = timestamp;
|
||||||
} else {
|
} else {
|
||||||
|
@ -106,17 +131,15 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
||||||
|
|
||||||
long oneMinute = 60 * 1000;
|
long oneMinute = 60 * 1000;
|
||||||
float factor = oneMinute / millis;
|
float factor = oneMinute / millis;
|
||||||
return (int) (stepsDelta * factor);
|
int result = (int) (stepsDelta * factor);
|
||||||
|
if (result > MAX_STEPS_PER_MINUTE) {
|
||||||
|
// ignore, return previous value instead
|
||||||
|
result = lastStepsPerMinute;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private BarLineChartBase mStepsPerMinuteHistoryChart;
|
|
||||||
private CustomBarChart mStepsPerMinuteCurrentChart;
|
|
||||||
private CustomBarChart mTotalStepsChart;
|
|
||||||
|
|
||||||
private Steps mSteps = new Steps();
|
|
||||||
|
|
||||||
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
@ -133,11 +156,29 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
||||||
|
|
||||||
private void refreshCurrentSteps(int steps, long timestamp) {
|
private void refreshCurrentSteps(int steps, long timestamp) {
|
||||||
mSteps.updateCurrentSteps(steps, timestamp);
|
mSteps.updateCurrentSteps(steps, timestamp);
|
||||||
|
if (++maxStepsResetCounter > RESET_COUNT) {
|
||||||
|
maxStepsResetCounter = 0;
|
||||||
|
mSteps.maxStepsPerMinute = 0;
|
||||||
|
}
|
||||||
// Or: count down the steps until goal reached? And then flash GOAL REACHED -> Set stretch goal
|
// Or: count down the steps until goal reached? And then flash GOAL REACHED -> Set stretch goal
|
||||||
|
LOG.info("Steps: " + steps + ", total: " + mSteps.getTotalSteps() + ", current: " + mSteps.getStepsPerMinute(false));
|
||||||
|
|
||||||
|
// refreshCurrentSteps();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshCurrentSteps() {
|
||||||
mTotalStepsChart.setSingleEntryYValue(mSteps.getTotalSteps());
|
mTotalStepsChart.setSingleEntryYValue(mSteps.getTotalSteps());
|
||||||
LOG.info("Steps: " + steps + ", total: " + mSteps.getTotalSteps() + ", current: " + mSteps.getStepsPerMinute());
|
YAxis stepsPerMinuteCurrentYAxis = mStepsPerMinuteCurrentChart.getAxisLeft();
|
||||||
mStepsPerMinuteCurrentChart.getAxisLeft().setAxisMaxValue(mSteps.getMaxStepsPerMinute());
|
int maxStepsPerMinute = mSteps.getMaxStepsPerMinute();
|
||||||
mStepsPerMinuteCurrentChart.setSingleEntryYValue(mSteps.getStepsPerMinute());
|
// int extraRoom = maxStepsPerMinute/5;
|
||||||
|
// buggy in MPAndroidChart? Disable.
|
||||||
|
// stepsPerMinuteCurrentYAxis.setAxisMaxValue(Math.max(MIN_STEPS_PER_MINUTE, maxStepsPerMinute + extraRoom));
|
||||||
|
LimitLine target = new LimitLine(maxStepsPerMinute);
|
||||||
|
stepsPerMinuteCurrentYAxis.removeAllLimitLines();
|
||||||
|
stepsPerMinuteCurrentYAxis.addLimitLine(target);
|
||||||
|
|
||||||
|
int stepsPerMinute = mSteps.getStepsPerMinute(true);
|
||||||
|
mStepsPerMinuteCurrentChart.setSingleEntryYValue(stepsPerMinute);
|
||||||
|
|
||||||
if (mStepsPerMinuteHistoryChart.getData() == null) {
|
if (mStepsPerMinuteHistoryChart.getData() == null) {
|
||||||
if (mSteps.getTotalSteps() == 0) {
|
if (mSteps.getTotalSteps() == 0) {
|
||||||
|
@ -150,7 +191,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
||||||
|
|
||||||
LineData historyData = (LineData) mStepsPerMinuteHistoryChart.getData();
|
LineData historyData = (LineData) mStepsPerMinuteHistoryChart.getData();
|
||||||
historyData.addXValue("");
|
historyData.addXValue("");
|
||||||
historyData.addEntry(new Entry(mSteps.getStepsPerMinute(), mHistorySet.getEntryCount()), 0);
|
historyData.addEntry(new Entry(stepsPerMinute, mHistorySet.getEntryCount()), 0);
|
||||||
|
|
||||||
mTotalStepsData.notifyDataSetChanged();
|
mTotalStepsData.notifyDataSetChanged();
|
||||||
mStepsPerMinuteData.notifyDataSetChanged();
|
mStepsPerMinuteData.notifyDataSetChanged();
|
||||||
|
@ -183,6 +224,51 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
||||||
return rootView;
|
return rootView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
if (pulseScheduler != null) {
|
||||||
|
pulseScheduler.shutdownNow();
|
||||||
|
pulseScheduler = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
pulseScheduler = startActivityPulse();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScheduledExecutorService startActivityPulse() {
|
||||||
|
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
service.scheduleAtFixedRate(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
FragmentActivity activity = LiveActivityFragment.this.getActivity();
|
||||||
|
if (activity != null && !activity.isFinishing() && !activity.isDestroyed()) {
|
||||||
|
activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
pulse();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 0, getPulseIntervalMillis(), TimeUnit.MILLISECONDS);
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called in the UI thread.
|
||||||
|
*/
|
||||||
|
private void pulse() {
|
||||||
|
refreshCurrentSteps();
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getPulseIntervalMillis() {
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onMadeVisibleInActivity() {
|
protected void onMadeVisibleInActivity() {
|
||||||
GBApplication.deviceService().onEnableRealtimeSteps(true);
|
GBApplication.deviceService().onEnableRealtimeSteps(true);
|
||||||
|
@ -208,7 +294,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
private BarDataSet setupCurrentChart(CustomBarChart chart, BarEntry entry, String title) {
|
private BarDataSet setupCurrentChart(CustomBarChart chart, BarEntry entry, String title) {
|
||||||
mStepsPerMinuteCurrentChart.getAxisLeft().setAxisMaxValue(300);
|
mStepsPerMinuteCurrentChart.getAxisLeft().setAxisMaxValue(MAX_STEPS_PER_MINUTE);
|
||||||
return setupCommonChart(chart, entry, title);
|
return setupCommonChart(chart, entry, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ public class WeekStepsChartFragment extends AbstractChartFragment {
|
||||||
data.setValueTextColor(Color.GRAY); //prevent tearing other graph elements with the black text. Another approach would be to hide the values cmpletely with data.setDrawValues(false);
|
data.setValueTextColor(Color.GRAY); //prevent tearing other graph elements with the black text. Another approach would be to hide the values cmpletely with data.setDrawValues(false);
|
||||||
|
|
||||||
LimitLine target = new LimitLine(mTargetSteps);
|
LimitLine target = new LimitLine(mTargetSteps);
|
||||||
barChart.getAxisLeft().getLimitLines().clear();
|
barChart.getAxisLeft().removeAllLimitLines();
|
||||||
barChart.getAxisLeft().addLimitLine(target);
|
barChart.getAxisLeft().addLimitLine(target);
|
||||||
|
|
||||||
setupLegend(barChart);
|
setupLegend(barChart);
|
||||||
|
|
|
@ -732,7 +732,9 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
||||||
|
|
||||||
private void handleRealtimeSteps(byte[] value) {
|
private void handleRealtimeSteps(byte[] value) {
|
||||||
int steps = 0xff & value[0] | (0xff & value[1]) << 8;
|
int steps = 0xff & value[0] | (0xff & value[1]) << 8;
|
||||||
LOG.debug("realtime steps: " + steps);
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("realtime steps: " + steps);
|
||||||
|
}
|
||||||
Intent intent = new Intent(DeviceService.ACTION_REALTIME_STEPS)
|
Intent intent = new Intent(DeviceService.ACTION_REALTIME_STEPS)
|
||||||
.putExtra(DeviceService.EXTRA_REALTIME_STEPS, steps)
|
.putExtra(DeviceService.EXTRA_REALTIME_STEPS, steps)
|
||||||
.putExtra(DeviceService.EXTRA_TIMESTAMP, System.currentTimeMillis());
|
.putExtra(DeviceService.EXTRA_TIMESTAMP, System.currentTimeMillis());
|
||||||
|
|
Loading…
Reference in New Issue
Block a user