Merge remote-tracking branch 'origin/master' into low_battery_notification

Conflicts:
	app/src/main/res/values/strings.xml
live-activity-data
Daniele Gobbetti 2015-08-26 15:46:33 +02:00
commit 3356a4b066
14 changed files with 459 additions and 163 deletions

View File

@ -0,0 +1,51 @@
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.view.ViewGroup;
import java.util.HashSet;
import java.util.Set;
public abstract class AbstractFragmentPagerAdapter extends FragmentStatePagerAdapter {
private Set<AbstractGBFragment> fragments = new HashSet<>();
private Object primaryFragment;
public AbstractFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Object fragment = super.instantiateItem(container, position);
if (fragment instanceof AbstractGBFragment) {
fragments.add((AbstractGBFragment) fragment);
}
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
fragments.remove(object);
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
if (object != primaryFragment) {
primaryFragment = object;
setCurrentFragment(primaryFragment);
}
}
private void setCurrentFragment(Object newCurrentFragment) {
for (AbstractGBFragment frag : fragments) {
if (frag != newCurrentFragment) {
frag.onMadeInvisibleInActivity();
} else {
frag.onMadeVisibleInActivityInternal();
}
}
}
}

View File

@ -0,0 +1,65 @@
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
/**
* Abstract base class for fragments. Provides hooks that are called when
* the fragment is made visible and invisible in the activity. also allows
* the fragment to define the title to be shown in the activity.
* @see AbstractGBFragmentActivity
*/
public abstract class AbstractGBFragment extends Fragment {
private boolean mVisibleInactivity;
/**
* Called when this fragment has been fully scrolled into the activity.
*
* @see #isVisibleInActivity()
* @see #onMadeInvisibleInActivity()
*/
protected void onMadeVisibleInActivity() {
updateActivityTitle();
}
/**
* Called when this fragment has been scrolled out of the activity.
* @see #isVisibleInActivity()
* @see #onMadeVisibleInActivity()
*/
protected void onMadeInvisibleInActivity() {
mVisibleInactivity = false;
}
/**
* Returns true if this fragment is currently visible in the hosting
* activity, not taking into account whether the screen is enabled at all.
*/
public boolean isVisibleInActivity() {
return mVisibleInactivity;
}
protected void updateActivityTitle() {
FragmentActivity activity = getActivity();
if (activity != null && !activity.isFinishing() && !activity.isDestroyed()) {
if (getTitle() != null) {
activity.setTitle(getTitle());
}
}
}
@Nullable
protected abstract CharSequence getTitle();
/**
* Internal
* @hide
*/
public void onMadeVisibleInActivityInternal() {
mVisibleInactivity = true;
if (isVisible()) {
onMadeVisibleInActivity();
}
}
}

View File

@ -0,0 +1,57 @@
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.content.Context;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.util.AttributeSet;
import android.view.View;
/**
* A base activity that supports paging through fragments by swiping.
* Subclasses will have to add a ViewPager to their layout and add something
* like this to hook it to the fragments:
*
* <pre>
* // Set up the ViewPager with the sections adapter.
* ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
* viewPager.setAdapter(getPagerAdapter());
* </pre>
*
* @see AbstractGBFragment
*/
public abstract class AbstractGBFragmentActivity extends FragmentActivity {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private AbstractFragmentPagerAdapter mSectionsPagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = createFragmentPagerAdapter(getSupportFragmentManager());
}
public AbstractFragmentPagerAdapter getPagerAdapter() {
return mSectionsPagerAdapter;
}
/**
* Creates a PagerAdapter that will create the fragments to be used with this
* activity. The fragments should typically extend AbstractGBFragment
* @param fragmentManager
* @return
*/
protected abstract AbstractFragmentPagerAdapter createFragmentPagerAdapter(FragmentManager fragmentManager);
}

View File

@ -170,8 +170,10 @@ public class ControlCenter extends Activity {
menu.removeItem(R.id.controlcenter_take_screenshot);
}
if (!selectedDevice.isConnected()) {
if (selectedDevice.getState() == GBDevice.State.NOT_CONNECTED) {
menu.removeItem(R.id.controlcenter_disconnect);
}
if (!selectedDevice.isInitialized()) {
menu.removeItem(R.id.controlcenter_find_device);
}

View File

@ -6,12 +6,8 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.LocalBroadcastManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.github.mikephil.charting.charts.BarLineChartBase;
import com.github.mikephil.charting.charts.Chart;
@ -33,6 +29,7 @@ import java.util.List;
import java.util.Set;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBFragment;
import nodomain.freeyourgadget.gadgetbridge.database.DBAccess;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
@ -43,8 +40,28 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
public abstract class AbstractChartFragment extends Fragment {
private static final Logger LOG = LoggerFactory.getLogger(ActivitySleepChartFragment.class);
/**
* 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()
* Broadcast events can be received by overriding #onReceive(Context,Intent).
* The chart can be refreshed by calling #refresh()
* Implement refreshInBackground(DBHandler, GBDevice) to fetch the samples from the DB,
* and add the samples to the chart. The actual rendering, which must be performed in the UI
* thread, must be done in #renderCharts().
* Access functionality of the hosting activity with #getHost()
*
* The hosting ChartsHost activity provides a section for displaying a date or date range
* being the basis for the chart, as well as two buttons for moving backwards and forward
* in time. The date is held by the activity, so that it can be shared by multiple chart
* fragments. It is still the responsibility of the (currently visible) chart fragment
* to set the desired date in the ChartsActivity via #setDateRange(Date,Date).
* The default implementations #handleDatePrev(Date,Date) and #handleDateNext(Date,Date)
* shift the date by one day.
*/
public abstract class AbstractChartFragment extends AbstractGBFragment {
protected int ANIM_TIME = 350;
private static final Logger LOG = LoggerFactory.getLogger(AbstractChartFragment.class);
private final Set<String> mIntentFilterActions;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@ -53,6 +70,13 @@ public abstract class AbstractChartFragment extends Fragment {
AbstractChartFragment.this.onReceive(context, intent);
}
};
private boolean mChartDirty = true;
public boolean isChartDirty() {
return mChartDirty;
}
public abstract String getTitle();
protected static final class ActivityConfig {
public final int type;
@ -66,9 +90,6 @@ public abstract class AbstractChartFragment extends Fragment {
}
}
private Date mStartDate;
private Date mEndDate;
protected ActivityConfig akActivity = new ActivityConfig(ActivityKind.TYPE_ACTIVITY, "Activity", Color.rgb(89, 178, 44));
protected ActivityConfig akLightSleep = new ActivityConfig(ActivityKind.TYPE_LIGHT_SLEEP, "Light Sleep", Color.rgb(182, 191, 255));
protected ActivityConfig akDeepSleep = new ActivityConfig(ActivityKind.TYPE_DEEP_SLEEP, "Deep Sleep", Color.rgb(76, 90, 255));
@ -92,8 +113,6 @@ public abstract class AbstractChartFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initDates();
IntentFilter filter = new IntentFilter();
for (String action : mIntentFilterActions) {
filter.addAction(action);
@ -101,24 +120,34 @@ public abstract class AbstractChartFragment extends Fragment {
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mReceiver, filter);
}
private void setStartDate(Date date) {
getHost().setStartDate(date);
}
private void setEndDate(Date date) {
getHost().setEndDate(date);
}
public Date getStartDate() {
return getHost().getStartDate();
}
public Date getEndDate() {
return getHost().getEndDate();
}
/**
* Called when this fragment has been fully scrolled into the activity.
*
* @see #isVisibleInActivity()
* @see #onMadeInvisibleInActivity()
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
updateDateInfo(mStartDate, mEndDate);
return view;
}
public void setStartDate(Date date) {
mStartDate = date;
}
public void setEndDate(Date endDate) {
mEndDate = endDate;
}
protected void initDates() {
setEndDate(new Date());
setStartDate(DateTimeUtils.shiftByDays(mEndDate, -1));
protected void onMadeVisibleInActivity() {
super.onMadeVisibleInActivity();
if (isChartDirty()) {
refresh();
}
}
@Override
@ -132,26 +161,62 @@ public abstract class AbstractChartFragment extends Fragment {
if (ChartsHost.REFRESH.equals(action)) {
refresh();
} else if (ChartsHost.DATE_NEXT.equals(action)) {
handleDateNext(mStartDate, mEndDate);
handleDateNext(getStartDate(), getEndDate());
} else if (ChartsHost.DATE_PREV.equals(action)) {
handleDatePrev(mStartDate, mEndDate);
handleDatePrev(getStartDate(), getEndDate());
}
}
/**
* Default implementation shifts the dates by one day, if visible
* and calls #refreshIfVisible().
* @param startDate
* @param endDate
*/
protected void handleDatePrev(Date startDate, Date endDate) {
shiftDates(startDate, endDate, -1);
if (isVisibleInActivity()) {
if (!shiftDates(startDate, endDate, -1)) {
return;
}
}
refreshIfVisible();
}
/**
* Default implementation shifts the dates by one day, if visible
* and calls #refreshIfVisible().
* @param startDate
* @param endDate
*/
protected void handleDateNext(Date startDate, Date endDate) {
shiftDates(startDate, endDate, +1);
if (isVisibleInActivity()) {
if (!shiftDates(startDate, endDate, +1)) {
return;
}
}
refreshIfVisible();
}
protected void shiftDates(Date startDate, Date endDate, int offset) {
protected void refreshIfVisible() {
if (isVisibleInActivity()) {
refresh();
} else {
mChartDirty = true;
}
}
/**
* Shifts the given dates by offset days. offset may be positive or negative.
* @param startDate
* @param endDate
* @param offset a positive or negative number of days to shift the dates
* @return true if the shift was successful and false otherwise
*/
protected boolean shiftDates(Date startDate, Date endDate, int offset) {
Date newStart = DateTimeUtils.shiftByDays(startDate, offset);
Date newEnd = DateTimeUtils.shiftByDays(endDate, offset);
setDateRange(newStart, newEnd);
refresh();
return setDateRange(newStart, newEnd);
}
protected Integer getColorFor(int activityKind) {
@ -250,7 +315,11 @@ public abstract class AbstractChartFragment extends Fragment {
* #renderCharts
*/
protected void refresh() {
createRefreshTask("Visualizing data", getActivity()).execute();
if (getHost().getDevice() != null) {
mChartDirty = false;
updateDateInfo(getStartDate(), getEndDate());
createRefreshTask("Visualizing data", getActivity()).execute();
}
}
/**
@ -258,19 +327,15 @@ public abstract class AbstractChartFragment extends Fragment {
* the charts. This will be called from a background task, so there must not be
* any UI access. #renderCharts will be automatically called after this method.
*/
protected abstract void refreshInBackground(DBHandler db);
protected abstract void refreshInBackground(DBHandler db, GBDevice device);
/**
* Performs a re-rendering of the chart.
* Triggers the actual (re-) rendering of the chart.
* Always called from the UI thread.
*/
protected abstract void renderCharts();
protected void refresh(GBDevice gbDevice, BarLineChartBase chart, List<ActivitySample> samples) {
if (gbDevice == null) {
return;
}
Calendar cal = GregorianCalendar.getInstance();
cal.clear();
Date date;
@ -380,6 +445,14 @@ public abstract class AbstractChartFragment extends Fragment {
}
}
/**
* Implement this to supply the samples to be displayed.
* @param db
* @param device
* @param tsFrom
* @param tsTo
* @return
*/
protected abstract List<ActivitySample> getSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo);
protected abstract void setupLegend(Chart chart);
@ -450,7 +523,7 @@ public abstract class AbstractChartFragment extends Fragment {
@Override
protected void doInBackground(DBHandler db) {
refreshInBackground(db);
refreshInBackground(db, getHost().getDevice());
}
@Override
@ -465,13 +538,23 @@ public abstract class AbstractChartFragment extends Fragment {
}
}
public void setDateRange(Date from, Date to) {
/**
* Returns true if the date was successfully shifted, and false if the shift
* was ignored, e.g. when the to-value is in the future.
* @param from
* @param to
*/
public boolean setDateRange(Date from, Date to) {
if (from.compareTo(to) > 0) {
throw new IllegalArgumentException("Bad date range: " +from + ".." + to);
}
mStartDate = from;
mEndDate = to;
updateDateInfo(mStartDate, mEndDate);
Date now = new Date();
if (to.after(now)) {
return false;
}
setStartDate(from);
setEndDate(to);
return true;
}
protected void updateDateInfo(Date from, Date to) {
@ -487,11 +570,11 @@ public abstract class AbstractChartFragment extends Fragment {
}
private int getTSEnd() {
return toTimestamp(mEndDate);
return toTimestamp(getEndDate());
}
private int getTSStart() {
return toTimestamp(mStartDate);
return toTimestamp(getStartDate());
}
private int toTimestamp(Date date) {

View File

@ -34,19 +34,12 @@ public class ActivitySleepChartFragment extends AbstractChartFragment {
private int mSmartAlarmTo = -1;
private int mTimestampFrom = -1;
private int mSmartAlarmGoneOff = -1;
private GBDevice mGBDevice = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_charts, container, false);
Bundle extras = getActivity().getIntent().getExtras();
if (extras != null) {
mGBDevice = extras.getParcelable(GBDevice.EXTRA_DEVICE);
}
mChart = (BarLineChartBase) rootView.findViewById(R.id.activitysleepchart);
setupChart();
@ -54,6 +47,11 @@ public class ActivitySleepChartFragment extends AbstractChartFragment {
return rootView;
}
@Override
public String getTitle() {
return getString(R.string.activity_sleepchart_activity_and_sleep);
}
private void setupChart() {
mChart.setBackgroundColor(BACKGROUND_COLOR);
mChart.setDescriptionColor(DESCRIPTION_COLOR);
@ -85,6 +83,7 @@ public class ActivitySleepChartFragment extends AbstractChartFragment {
yAxisRight.setDrawTopYLabelEntry(false);
yAxisRight.setTextColor(CHART_TEXT_COLOR);
// refresh immediately instead of use refreshIfVisible(), for perceived performance
refresh();
}
@ -104,15 +103,15 @@ public class ActivitySleepChartFragment extends AbstractChartFragment {
}
@Override
protected void refreshInBackground(DBHandler db) {
List<ActivitySample> samples = getSamples(db, mGBDevice);
refresh(mGBDevice, mChart, samples);
protected void refreshInBackground(DBHandler db, GBDevice device) {
List<ActivitySample> samples = getSamples(db, device);
refresh(device, mChart, samples);
mChart.getLegend().setTextColor(LEGEND_TEXT_COLOR);
}
protected void renderCharts() {
mChart.animateX(500, Easing.EasingOption.EaseInOutQuart);
mChart.animateX(ANIM_TIME, Easing.EasingOption.EaseInOutQuart);
}
protected void setupLegend(Chart chart) {

View File

@ -6,11 +6,10 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuItem;
@ -22,37 +21,29 @@ import android.widget.TextView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Locale;
import java.util.Date;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractFragmentPagerAdapter;
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBFragmentActivity;
import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
public class ChartsActivity extends FragmentActivity implements ChartsHost {
public class ChartsActivity extends AbstractGBFragmentActivity implements ChartsHost {
private static final Logger LOG = LoggerFactory.getLogger(ChartsActivity.class);
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
private ProgressBar mProgressBar;
private Button mPrevButton;
private Button mNextButton;
private TextView mDateControl;
private Date mStartDate;
private Date mEndDate;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@ -61,8 +52,6 @@ public class ChartsActivity extends FragmentActivity implements ChartsHost {
case ControlCenter.ACTION_QUIT:
finish();
break;
case ControlCenter.ACTION_REFRESH_DEVICELIST:
break;
case GBDevice.ACTION_DEVICE_CHANGED:
GBDevice dev = intent.getParcelableExtra(GBDevice.EXTRA_DEVICE);
refreshBusyState(dev);
@ -70,6 +59,7 @@ public class ChartsActivity extends FragmentActivity implements ChartsHost {
}
}
};
private GBDevice mGBDevice;
private void refreshBusyState(GBDevice dev) {
if (dev.isBusy()) {
@ -88,20 +78,23 @@ public class ChartsActivity extends FragmentActivity implements ChartsHost {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_charts);
initDates();
IntentFilter filterLocal = new IntentFilter();
filterLocal.addAction(ControlCenter.ACTION_QUIT);
filterLocal.addAction(ControlCenter.ACTION_REFRESH_DEVICELIST);
filterLocal.addAction(GBDevice.ACTION_DEVICE_CHANGED);
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
Bundle extras = getIntent().getExtras();
if (extras != null) {
mGBDevice = extras.getParcelable(GBDevice.EXTRA_DEVICE);
} else {
throw new IllegalArgumentException("Must provide a device when invoking this activity");
}
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(getPagerAdapter());
mProgressBar = (ProgressBar) findViewById(R.id.charts_progress);
mPrevButton = (Button) findViewById(R.id.charts_previous);
@ -122,6 +115,36 @@ public class ChartsActivity extends FragmentActivity implements ChartsHost {
mDateControl = (TextView) findViewById(R.id.charts_text_date);
}
protected void initDates() {
setEndDate(new Date());
setStartDate(DateTimeUtils.shiftByDays(getEndDate(), -1));
}
@Override
public GBDevice getDevice() {
return mGBDevice;
}
@Override
public void setStartDate(Date startDate) {
mStartDate = startDate;
}
@Override
public void setEndDate(Date endDate) {
mEndDate = endDate;
}
@Override
public Date getStartDate() {
return mStartDate;
}
@Override
public Date getEndDate() {
return mEndDate;
}
private void handleNextButtonClicked() {
LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(DATE_NEXT));
}
@ -161,11 +184,16 @@ public class ChartsActivity extends FragmentActivity implements ChartsHost {
mDateControl.setText(dateInfo);
}
@Override
protected AbstractFragmentPagerAdapter createFragmentPagerAdapter(FragmentManager fragmentManager) {
return new SectionsPagerAdapter(fragmentManager);
}
/**
* A {@link FragmentStatePagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public static class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public static class SectionsPagerAdapter extends AbstractFragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
@ -191,19 +219,5 @@ public class ChartsActivity extends FragmentActivity implements ChartsHost {
// Show 3 total pages.
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return "Today".toUpperCase(l);
case 1:
return "Week".toUpperCase(l);
case 2:
return "Month".toUpperCase(l);
}
return null;
}
}
}

View File

@ -1,9 +1,20 @@
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
public interface ChartsHost {
public static final String DATE_PREV = ChartsActivity.class.getName().concat(".date_prev");
public static final String DATE_NEXT = ChartsActivity.class.getName().concat(".date_next");
public static final String REFRESH = ChartsActivity.class.getName().concat(".refresh");
import java.util.Date;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
public interface ChartsHost {
static final String DATE_PREV = ChartsActivity.class.getName().concat(".date_prev");
static final String DATE_NEXT = ChartsActivity.class.getName().concat(".date_next");
static final String REFRESH = ChartsActivity.class.getName().concat(".refresh");
GBDevice getDevice();
void setStartDate(Date startDate);
void setEndDate(Date endDate);
Date getStartDate();
Date getEndDate();
void setDateInfo(String dateInfo);
}

View File

@ -44,17 +44,13 @@ public class SleepChartFragment extends AbstractChartFragment {
private int mSmartAlarmTo = -1;
private int mTimestampFrom = -1;
private int mSmartAlarmGoneOff = -1;
private GBDevice mGBDevice = null;
@Override
protected void refreshInBackground(DBHandler db) {
List<ActivitySample> samples = getSamples(db);
refresh(mGBDevice, mActivityChart, samples);
refreshSleepAmounts(mGBDevice, mSleepAmountChart, samples);
}
protected void refreshInBackground(DBHandler db, GBDevice device) {
List<ActivitySample> samples = getSamples(db, device);
private List<ActivitySample> getSamples(DBHandler db) {
return getSamples(db, mGBDevice);
refresh(device, mActivityChart, samples);
refreshSleepAmounts(device, mSleepAmountChart, samples);
}
private void refreshSleepAmounts(GBDevice mGBDevice, PieChart pieChart, List<ActivitySample> samples) {
@ -87,22 +83,23 @@ public class SleepChartFragment extends AbstractChartFragment {
//setupLegend(pieChart);
}
@Override
public String getTitle() {
return getString(R.string.sleepchart_your_sleep);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_sleepchart, container, false);
Bundle extras = getActivity().getIntent().getExtras();
if (extras != null) {
mGBDevice = extras.getParcelable(GBDevice.EXTRA_DEVICE);
}
mActivityChart = (BarLineChartBase) rootView.findViewById(R.id.sleepchart);
mSleepAmountChart = (PieChart) rootView.findViewById(R.id.sleepchart_pie_light_deep);
setupActivityChart();
setupSleepAmountChart();
// refresh immediately instead of use refreshIfVisible(), for perceived performance
refresh();
return rootView;
@ -180,7 +177,7 @@ public class SleepChartFragment extends AbstractChartFragment {
}
protected void renderCharts() {
mActivityChart.animateX(500, Easing.EasingOption.EaseInOutQuart);
mActivityChart.animateX(ANIM_TIME, Easing.EasingOption.EaseInOutQuart);
mSleepAmountChart.invalidate();
}
}

View File

@ -44,14 +44,12 @@ public class WeekStepsChartFragment extends AbstractChartFragment {
private BarLineChartBase mWeekStepsChart;
private PieChart mTodayStepsChart;
private GBDevice mGBDevice = null;
@Override
protected void refreshInBackground(DBHandler db) {
protected void refreshInBackground(DBHandler db, GBDevice device) {
Calendar day = Calendar.getInstance();
//NB: we could have omitted the day, but this way we can move things to the past easily
refreshDaySteps(db, mTodayStepsChart, day);
refreshWeekBeforeSteps(db, mWeekStepsChart, day);
refreshDaySteps(db, mTodayStepsChart, day, device);
refreshWeekBeforeSteps(db, mWeekStepsChart, day, device);
}
@Override
@ -60,7 +58,7 @@ public class WeekStepsChartFragment extends AbstractChartFragment {
mTodayStepsChart.invalidate();
}
private void refreshWeekBeforeSteps(DBHandler db, BarLineChartBase barChart, Calendar day) {
private void refreshWeekBeforeSteps(DBHandler db, BarLineChartBase barChart, Calendar day, GBDevice device) {
ActivityAnalysis analysis = new ActivityAnalysis();
@ -69,7 +67,7 @@ public class WeekStepsChartFragment extends AbstractChartFragment {
List<String> labels = new ArrayList<>();
for (int counter = 0; counter < 7; counter++) {
entries.add(new BarEntry(analysis.calculateTotalSteps(getSamplesOfDay(db, day)), counter));
entries.add(new BarEntry(analysis.calculateTotalSteps(getSamplesOfDay(db, day, device)), counter));
labels.add(day.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, mLocale));
day.add(Calendar.DATE, 1);
}
@ -89,10 +87,10 @@ public class WeekStepsChartFragment extends AbstractChartFragment {
barChart.getLegend().setEnabled(false);
}
private void refreshDaySteps(DBHandler db, PieChart pieChart, Calendar day) {
private void refreshDaySteps(DBHandler db, PieChart pieChart, Calendar day, GBDevice device) {
ActivityAnalysis analysis = new ActivityAnalysis();
int totalSteps = analysis.calculateTotalSteps(getSamplesOfDay(db, day));
int totalSteps = analysis.calculateTotalSteps(getSamplesOfDay(db, day, device));
pieChart.setCenterText(NumberFormat.getNumberInstance(mLocale).format(totalSteps));
PieData data = new PieData();
@ -128,13 +126,9 @@ public class WeekStepsChartFragment extends AbstractChartFragment {
View rootView = inflater.inflate(R.layout.fragment_sleepchart, container, false);
Bundle extras = getActivity().getIntent().getExtras();
if (extras != null) {
mGBDevice = extras.getParcelable(GBDevice.EXTRA_DEVICE);
}
if(mGBDevice != null) {
mTargetSteps = MiBandCoordinator.getFitnessGoal(mGBDevice.getAddress());
GBDevice device = getHost().getDevice();
if(device != null) {
mTargetSteps = MiBandCoordinator.getFitnessGoal(device.getAddress());
}
mWeekStepsChart = (BarLineChartBase) rootView.findViewById(R.id.sleepchart);
@ -143,11 +137,17 @@ public class WeekStepsChartFragment extends AbstractChartFragment {
setupWeekStepsChart();
setupTodayStepsChart();
// refresh immediately instead of use refreshIfVisible(), for perceived performance
refresh();
return rootView;
}
@Override
public String getTitle() {
return getString(R.string.weekstepschart_steps_a_week);
}
private void setupTodayStepsChart() {
mTodayStepsChart.setBackgroundColor(BACKGROUND_COLOR);
mTodayStepsChart.setDescriptionColor(DESCRIPTION_COLOR);
@ -196,7 +196,7 @@ public class WeekStepsChartFragment extends AbstractChartFragment {
chart.getLegend().setTextColor(LEGEND_TEXT_COLOR);
}
private List<ActivitySample> getSamplesOfDay(DBHandler db, Calendar day) {
private List<ActivitySample> getSamplesOfDay(DBHandler db, Calendar day, GBDevice device) {
int startTs;
int endTs;
@ -210,7 +210,7 @@ public class WeekStepsChartFragment extends AbstractChartFragment {
day.set(Calendar.SECOND, 59);
endTs = (int) (day.getTimeInMillis() / 1000);
return getSamples(db, mGBDevice, startTs, endTs);
return getSamples(db, device, startTs, endTs);
}
@Override

View File

@ -0,0 +1,27 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity$PlaceholderFragment"
android:orientation="horizontal">
<com.github.mikephil.charting.charts.PieChart
android:id="@+id/sleepchart_pie_light_deep"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="40">
</com.github.mikephil.charting.charts.PieChart>
<nodomain.freeyourgadget.gadgetbridge.activities.charts.CustomBarChart
android:id="@+id/sleepchart"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="20" />
<!--<TextView-->
<!--android:text="Test"-->
<!--android:layout_width="fill_parent"-->
<!--android:layout_height="fill_parent"-->
<!--android:layout_weight="20" />-->
</LinearLayout>

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<nodomain.freeyourgadget.gadgetbridge.activities.charts.CustomBarChart
android:id="@+id/sleepchart2"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>

View File

@ -4,13 +4,6 @@
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity$PlaceholderFragment"
android:orientation="vertical">
<nodomain.freeyourgadget.gadgetbridge.activities.charts.CustomBarChart
android:id="@+id/sleepchart"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="20" />
<com.github.mikephil.charting.charts.PieChart
android:id="@+id/sleepchart_pie_light_deep"
android:layout_width="fill_parent"
@ -18,10 +11,17 @@
android:layout_weight="20">
</com.github.mikephil.charting.charts.PieChart>
<TextView
android:text="Test"
<nodomain.freeyourgadget.gadgetbridge.activities.charts.CustomBarChart
android:id="@+id/sleepchart"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="20" />
<!--<TextView-->
<!--android:text="Test"-->
<!--android:layout_width="fill_parent"-->
<!--android:layout_height="fill_parent"-->
<!--android:layout_weight="20" />-->
</LinearLayout>

View File

@ -166,4 +166,7 @@
<string name="notif_battery_low_percent">%1$s battery left: %2$s%%</string>
<string name="notif_battery_low_bigtext_last_charge_time">Last charge: %s \n</string>
<string name="notif_battery_low_bigtext_number_of_charges">Number of charges: %s</string>
<string name="sleepchart_your_sleep">Your Sleep</string>
<string name="weekstepschart_steps_a_week">Steps a week</string>
<string name="activity_sleepchart_activity_and_sleep">Your Activity and Sleep</string>
</resources>