mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-01-25 00:57:33 +01:00
Add support for REM sleep
This commit is contained in:
parent
28a26710d9
commit
a919286496
@ -116,6 +116,11 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
return coordinator != null && coordinator.supportsHeartRateMeasurement(device);
|
return coordinator != null && coordinator.supportsHeartRateMeasurement(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean supportsRemSleep(GBDevice device) {
|
||||||
|
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device);
|
||||||
|
return coordinator != null && coordinator.supportsRemSleep();
|
||||||
|
}
|
||||||
|
|
||||||
protected static final class ActivityConfig {
|
protected static final class ActivityConfig {
|
||||||
public final int type;
|
public final int type;
|
||||||
public final String label;
|
public final String label;
|
||||||
@ -131,6 +136,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
protected ActivityConfig akActivity;
|
protected ActivityConfig akActivity;
|
||||||
protected ActivityConfig akLightSleep;
|
protected ActivityConfig akLightSleep;
|
||||||
protected ActivityConfig akDeepSleep;
|
protected ActivityConfig akDeepSleep;
|
||||||
|
protected ActivityConfig akRemSleep;
|
||||||
protected ActivityConfig akNotWorn;
|
protected ActivityConfig akNotWorn;
|
||||||
|
|
||||||
|
|
||||||
@ -142,6 +148,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
protected int HEARTRATE_FILL_COLOR;
|
protected int HEARTRATE_FILL_COLOR;
|
||||||
protected int AK_ACTIVITY_COLOR;
|
protected int AK_ACTIVITY_COLOR;
|
||||||
protected int AK_DEEP_SLEEP_COLOR;
|
protected int AK_DEEP_SLEEP_COLOR;
|
||||||
|
protected int AK_REM_SLEEP_COLOR;
|
||||||
protected int AK_LIGHT_SLEEP_COLOR;
|
protected int AK_LIGHT_SLEEP_COLOR;
|
||||||
protected int AK_NOT_WORN_COLOR;
|
protected int AK_NOT_WORN_COLOR;
|
||||||
|
|
||||||
@ -194,6 +201,8 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
AK_DEEP_SLEEP_COLOR = runningColor.data;
|
AK_DEEP_SLEEP_COLOR = runningColor.data;
|
||||||
getContext().getTheme().resolveAttribute(R.attr.chart_light_sleep, runningColor, true);
|
getContext().getTheme().resolveAttribute(R.attr.chart_light_sleep, runningColor, true);
|
||||||
AK_LIGHT_SLEEP_COLOR = runningColor.data;
|
AK_LIGHT_SLEEP_COLOR = runningColor.data;
|
||||||
|
getContext().getTheme().resolveAttribute(R.attr.chart_rem_sleep, runningColor, true);
|
||||||
|
AK_REM_SLEEP_COLOR = runningColor.data;
|
||||||
getContext().getTheme().resolveAttribute(R.attr.chart_not_worn, runningColor, true);
|
getContext().getTheme().resolveAttribute(R.attr.chart_not_worn, runningColor, true);
|
||||||
AK_NOT_WORN_COLOR = runningColor.data;
|
AK_NOT_WORN_COLOR = runningColor.data;
|
||||||
|
|
||||||
@ -203,6 +212,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
akActivity = new ActivityConfig(ActivityKind.TYPE_ACTIVITY, getString(R.string.abstract_chart_fragment_kind_activity), AK_ACTIVITY_COLOR);
|
akActivity = new ActivityConfig(ActivityKind.TYPE_ACTIVITY, getString(R.string.abstract_chart_fragment_kind_activity), AK_ACTIVITY_COLOR);
|
||||||
akLightSleep = new ActivityConfig(ActivityKind.TYPE_LIGHT_SLEEP, getString(R.string.abstract_chart_fragment_kind_light_sleep), AK_LIGHT_SLEEP_COLOR);
|
akLightSleep = new ActivityConfig(ActivityKind.TYPE_LIGHT_SLEEP, getString(R.string.abstract_chart_fragment_kind_light_sleep), AK_LIGHT_SLEEP_COLOR);
|
||||||
akDeepSleep = new ActivityConfig(ActivityKind.TYPE_DEEP_SLEEP, getString(R.string.abstract_chart_fragment_kind_deep_sleep), AK_DEEP_SLEEP_COLOR);
|
akDeepSleep = new ActivityConfig(ActivityKind.TYPE_DEEP_SLEEP, getString(R.string.abstract_chart_fragment_kind_deep_sleep), AK_DEEP_SLEEP_COLOR);
|
||||||
|
akRemSleep = new ActivityConfig(ActivityKind.TYPE_REM_SLEEP, getString(R.string.abstract_chart_fragment_kind_rem_sleep), AK_REM_SLEEP_COLOR);
|
||||||
akNotWorn = new ActivityConfig(ActivityKind.TYPE_NOT_WORN, getString(R.string.abstract_chart_fragment_kind_not_worn), AK_NOT_WORN_COLOR);
|
akNotWorn = new ActivityConfig(ActivityKind.TYPE_NOT_WORN, getString(R.string.abstract_chart_fragment_kind_not_worn), AK_NOT_WORN_COLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,6 +341,8 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
return akDeepSleep.color;
|
return akDeepSleep.color;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case ActivityKind.TYPE_LIGHT_SLEEP:
|
||||||
return akLightSleep.color;
|
return akLightSleep.color;
|
||||||
|
case ActivityKind.TYPE_REM_SLEEP:
|
||||||
|
return akRemSleep.color;
|
||||||
case ActivityKind.TYPE_ACTIVITY:
|
case ActivityKind.TYPE_ACTIVITY:
|
||||||
return akActivity.color;
|
return akActivity.color;
|
||||||
}
|
}
|
||||||
@ -456,6 +468,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
List<Entry> activityEntries = new ArrayList<>(numEntries);
|
List<Entry> activityEntries = new ArrayList<>(numEntries);
|
||||||
List<Entry> deepSleepEntries = new ArrayList<>(numEntries);
|
List<Entry> deepSleepEntries = new ArrayList<>(numEntries);
|
||||||
List<Entry> lightSleepEntries = new ArrayList<>(numEntries);
|
List<Entry> lightSleepEntries = new ArrayList<>(numEntries);
|
||||||
|
List<Entry> remSleepEntries = new ArrayList<>(numEntries);
|
||||||
List<Entry> notWornEntries = new ArrayList<>(numEntries);
|
List<Entry> notWornEntries = new ArrayList<>(numEntries);
|
||||||
boolean hr = supportsHeartrate(gbDevice);
|
boolean hr = supportsHeartrate(gbDevice);
|
||||||
List<Entry> heartrateEntries = hr ? new ArrayList<Entry>(numEntries) : null;
|
List<Entry> heartrateEntries = hr ? new ArrayList<Entry>(numEntries) : null;
|
||||||
@ -490,6 +503,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
deepSleepEntries.add(createLineEntry(0, ts - 1));
|
deepSleepEntries.add(createLineEntry(0, ts - 1));
|
||||||
|
|
||||||
lightSleepEntries.add(createLineEntry(0, ts));
|
lightSleepEntries.add(createLineEntry(0, ts));
|
||||||
|
remSleepEntries.add(createLineEntry(0, ts));
|
||||||
notWornEntries.add(createLineEntry(0, ts));
|
notWornEntries.add(createLineEntry(0, ts));
|
||||||
activityEntries.add(createLineEntry(0, ts));
|
activityEntries.add(createLineEntry(0, ts));
|
||||||
}
|
}
|
||||||
@ -500,17 +514,30 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
lightSleepEntries.add(createLineEntry(0, ts - 1));
|
lightSleepEntries.add(createLineEntry(0, ts - 1));
|
||||||
|
|
||||||
deepSleepEntries.add(createLineEntry(0, ts));
|
deepSleepEntries.add(createLineEntry(0, ts));
|
||||||
|
remSleepEntries.add(createLineEntry(0, ts));
|
||||||
notWornEntries.add(createLineEntry(0, ts));
|
notWornEntries.add(createLineEntry(0, ts));
|
||||||
activityEntries.add(createLineEntry(0, ts));
|
activityEntries.add(createLineEntry(0, ts));
|
||||||
}
|
}
|
||||||
lightSleepEntries.add(createLineEntry(value, ts));
|
lightSleepEntries.add(createLineEntry(value, ts));
|
||||||
break;
|
break;
|
||||||
|
case ActivityKind.TYPE_REM_SLEEP:
|
||||||
|
if (last_type != type) {
|
||||||
|
remSleepEntries.add(createLineEntry(0, ts - 1));
|
||||||
|
|
||||||
|
lightSleepEntries.add(createLineEntry(0, ts));
|
||||||
|
deepSleepEntries.add(createLineEntry(0, ts));
|
||||||
|
notWornEntries.add(createLineEntry(0, ts));
|
||||||
|
activityEntries.add(createLineEntry(0, ts));
|
||||||
|
}
|
||||||
|
remSleepEntries.add(createLineEntry(value, ts));
|
||||||
|
break;
|
||||||
case ActivityKind.TYPE_NOT_WORN:
|
case ActivityKind.TYPE_NOT_WORN:
|
||||||
if (last_type != type) {
|
if (last_type != type) {
|
||||||
notWornEntries.add(createLineEntry(0, ts - 1));
|
notWornEntries.add(createLineEntry(0, ts - 1));
|
||||||
|
|
||||||
lightSleepEntries.add(createLineEntry(0, ts));
|
lightSleepEntries.add(createLineEntry(0, ts));
|
||||||
deepSleepEntries.add(createLineEntry(0, ts));
|
deepSleepEntries.add(createLineEntry(0, ts));
|
||||||
|
remSleepEntries.add(createLineEntry(0, ts));
|
||||||
activityEntries.add(createLineEntry(0, ts));
|
activityEntries.add(createLineEntry(0, ts));
|
||||||
}
|
}
|
||||||
notWornEntries.add(createLineEntry(SleepUtils.Y_VALUE_DEEP_SLEEP, ts)); //a small value, just to show something on the graphs
|
notWornEntries.add(createLineEntry(SleepUtils.Y_VALUE_DEEP_SLEEP, ts)); //a small value, just to show something on the graphs
|
||||||
@ -528,6 +555,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
lightSleepEntries.add(createLineEntry(0, ts));
|
lightSleepEntries.add(createLineEntry(0, ts));
|
||||||
notWornEntries.add(createLineEntry(0, ts));
|
notWornEntries.add(createLineEntry(0, ts));
|
||||||
deepSleepEntries.add(createLineEntry(0, ts));
|
deepSleepEntries.add(createLineEntry(0, ts));
|
||||||
|
remSleepEntries.add(createLineEntry(0, ts));
|
||||||
}
|
}
|
||||||
activityEntries.add(createLineEntry(value, ts));
|
activityEntries.add(createLineEntry(value, ts));
|
||||||
}
|
}
|
||||||
@ -576,6 +604,10 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
lineDataSets.add(deepSleepSet);
|
lineDataSets.add(deepSleepSet);
|
||||||
LineDataSet lightSleepSet = createDataSet(lightSleepEntries, akLightSleep.color, "Light Sleep");
|
LineDataSet lightSleepSet = createDataSet(lightSleepEntries, akLightSleep.color, "Light Sleep");
|
||||||
lineDataSets.add(lightSleepSet);
|
lineDataSets.add(lightSleepSet);
|
||||||
|
if (supportsRemSleep(gbDevice)) {
|
||||||
|
LineDataSet remSleepSet = createDataSet(remSleepEntries, akRemSleep.color, "REM Sleep");
|
||||||
|
lineDataSets.add(remSleepSet);
|
||||||
|
}
|
||||||
LineDataSet notWornSet = createDataSet(notWornEntries, akNotWorn.color, "Not worn");
|
LineDataSet notWornSet = createDataSet(notWornEntries, akNotWorn.color, "Not worn");
|
||||||
lineDataSets.add(notWornSet);
|
lineDataSets.add(notWornSet);
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ public class ActivityAnalysis {
|
|||||||
public ActivityAmounts calculateActivityAmounts(List<? extends ActivitySample> samples) {
|
public ActivityAmounts calculateActivityAmounts(List<? extends ActivitySample> samples) {
|
||||||
ActivityAmount deepSleep = new ActivityAmount(ActivityKind.TYPE_DEEP_SLEEP);
|
ActivityAmount deepSleep = new ActivityAmount(ActivityKind.TYPE_DEEP_SLEEP);
|
||||||
ActivityAmount lightSleep = new ActivityAmount(ActivityKind.TYPE_LIGHT_SLEEP);
|
ActivityAmount lightSleep = new ActivityAmount(ActivityKind.TYPE_LIGHT_SLEEP);
|
||||||
|
ActivityAmount remSleep = new ActivityAmount(ActivityKind.TYPE_REM_SLEEP);
|
||||||
ActivityAmount notWorn = new ActivityAmount(ActivityKind.TYPE_NOT_WORN);
|
ActivityAmount notWorn = new ActivityAmount(ActivityKind.TYPE_NOT_WORN);
|
||||||
ActivityAmount activity = new ActivityAmount(ActivityKind.TYPE_ACTIVITY);
|
ActivityAmount activity = new ActivityAmount(ActivityKind.TYPE_ACTIVITY);
|
||||||
|
|
||||||
@ -53,6 +54,9 @@ public class ActivityAnalysis {
|
|||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case ActivityKind.TYPE_LIGHT_SLEEP:
|
||||||
amount = lightSleep;
|
amount = lightSleep;
|
||||||
break;
|
break;
|
||||||
|
case ActivityKind.TYPE_REM_SLEEP:
|
||||||
|
amount = remSleep;
|
||||||
|
break;
|
||||||
case ActivityKind.TYPE_NOT_WORN:
|
case ActivityKind.TYPE_NOT_WORN:
|
||||||
amount = notWorn;
|
amount = notWorn;
|
||||||
break;
|
break;
|
||||||
@ -108,6 +112,9 @@ public class ActivityAnalysis {
|
|||||||
if (lightSleep.getTotalSeconds() > 0) {
|
if (lightSleep.getTotalSeconds() > 0) {
|
||||||
result.addAmount(lightSleep);
|
result.addAmount(lightSleep);
|
||||||
}
|
}
|
||||||
|
if (remSleep.getTotalSeconds() > 0) {
|
||||||
|
result.addAmount(remSleep);
|
||||||
|
}
|
||||||
if (activity.getTotalSeconds() > 0) {
|
if (activity.getTotalSeconds() > 0) {
|
||||||
result.addAmount(activity);
|
result.addAmount(activity);
|
||||||
}
|
}
|
||||||
|
@ -166,6 +166,13 @@ public class ActivitySleepChartFragment extends AbstractChartFragment {
|
|||||||
deepSleepEntry.formColor = akDeepSleep.color;
|
deepSleepEntry.formColor = akDeepSleep.color;
|
||||||
legendEntries.add(deepSleepEntry);
|
legendEntries.add(deepSleepEntry);
|
||||||
|
|
||||||
|
if (supportsRemSleep(getChartsHost().getDevice())) {
|
||||||
|
LegendEntry remSleepEntry = new LegendEntry();
|
||||||
|
remSleepEntry.label = akRemSleep.label;
|
||||||
|
remSleepEntry.formColor = akRemSleep.color;
|
||||||
|
legendEntries.add(remSleepEntry);
|
||||||
|
}
|
||||||
|
|
||||||
LegendEntry notWornEntry = new LegendEntry();
|
LegendEntry notWornEntry = new LegendEntry();
|
||||||
notWornEntry.label = akNotWorn.label;
|
notWornEntry.label = akNotWorn.label;
|
||||||
notWornEntry.formColor = akNotWorn.color;
|
notWornEntry.formColor = akNotWorn.color;
|
||||||
|
@ -36,6 +36,7 @@ public class SleepAnalysis {
|
|||||||
Date sleepEnd = null;
|
Date sleepEnd = null;
|
||||||
long lightSleepDuration = 0;
|
long lightSleepDuration = 0;
|
||||||
long deepSleepDuration = 0;
|
long deepSleepDuration = 0;
|
||||||
|
long remSleepDuration = 0;
|
||||||
long durationSinceLastSleep = 0;
|
long durationSinceLastSleep = 0;
|
||||||
|
|
||||||
for (ActivitySample sample : samples) {
|
for (ActivitySample sample : samples) {
|
||||||
@ -47,12 +48,13 @@ public class SleepAnalysis {
|
|||||||
durationSinceLastSleep = 0;
|
durationSinceLastSleep = 0;
|
||||||
} else {
|
} else {
|
||||||
//exclude "not worn" times from sleep sessions as this makes a discrepancy with the charts
|
//exclude "not worn" times from sleep sessions as this makes a discrepancy with the charts
|
||||||
if (lightSleepDuration + deepSleepDuration > MIN_SESSION_LENGTH)
|
if (lightSleepDuration + deepSleepDuration + remSleepDuration > MIN_SESSION_LENGTH)
|
||||||
result.add(new SleepSession(sleepStart, sleepEnd, lightSleepDuration, deepSleepDuration));
|
result.add(new SleepSession(sleepStart, sleepEnd, lightSleepDuration, deepSleepDuration, remSleepDuration));
|
||||||
sleepStart = null;
|
sleepStart = null;
|
||||||
sleepEnd = null;
|
sleepEnd = null;
|
||||||
lightSleepDuration = 0;
|
lightSleepDuration = 0;
|
||||||
deepSleepDuration = 0;
|
deepSleepDuration = 0;
|
||||||
|
remSleepDuration = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (previousSample != null) {
|
if (previousSample != null) {
|
||||||
@ -61,29 +63,34 @@ public class SleepAnalysis {
|
|||||||
lightSleepDuration += durationSinceLastSample;
|
lightSleepDuration += durationSinceLastSample;
|
||||||
} else if (sample.getKind() == ActivityKind.TYPE_DEEP_SLEEP) {
|
} else if (sample.getKind() == ActivityKind.TYPE_DEEP_SLEEP) {
|
||||||
deepSleepDuration += durationSinceLastSample;
|
deepSleepDuration += durationSinceLastSample;
|
||||||
|
} else if (sample.getKind() == ActivityKind.TYPE_REM_SLEEP) {
|
||||||
|
remSleepDuration += durationSinceLastSample;
|
||||||
} else {
|
} else {
|
||||||
durationSinceLastSleep += durationSinceLastSample;
|
durationSinceLastSleep += durationSinceLastSample;
|
||||||
if (sleepStart != null && durationSinceLastSleep > MAX_WAKE_PHASE_LENGTH) {
|
if (sleepStart != null && durationSinceLastSleep > MAX_WAKE_PHASE_LENGTH) {
|
||||||
if (lightSleepDuration + deepSleepDuration > MIN_SESSION_LENGTH)
|
if (lightSleepDuration + deepSleepDuration + remSleepDuration > MIN_SESSION_LENGTH)
|
||||||
result.add(new SleepSession(sleepStart, sleepEnd, lightSleepDuration, deepSleepDuration));
|
result.add(new SleepSession(sleepStart, sleepEnd, lightSleepDuration, deepSleepDuration, remSleepDuration));
|
||||||
sleepStart = null;
|
sleepStart = null;
|
||||||
sleepEnd = null;
|
sleepEnd = null;
|
||||||
lightSleepDuration = 0;
|
lightSleepDuration = 0;
|
||||||
deepSleepDuration = 0;
|
deepSleepDuration = 0;
|
||||||
|
remSleepDuration = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
previousSample = sample;
|
previousSample = sample;
|
||||||
}
|
}
|
||||||
if (lightSleepDuration + deepSleepDuration > MIN_SESSION_LENGTH) {
|
if (lightSleepDuration + deepSleepDuration + remSleepDuration > MIN_SESSION_LENGTH) {
|
||||||
result.add(new SleepSession(sleepStart, sleepEnd, lightSleepDuration, deepSleepDuration));
|
result.add(new SleepSession(sleepStart, sleepEnd, lightSleepDuration, deepSleepDuration, remSleepDuration));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSleep(ActivitySample sample) {
|
private boolean isSleep(ActivitySample sample) {
|
||||||
return sample.getKind() == ActivityKind.TYPE_DEEP_SLEEP || sample.getKind() == ActivityKind.TYPE_LIGHT_SLEEP;
|
return sample.getKind() == ActivityKind.TYPE_DEEP_SLEEP ||
|
||||||
|
sample.getKind() == ActivityKind.TYPE_LIGHT_SLEEP ||
|
||||||
|
sample.getKind() == ActivityKind.TYPE_REM_SLEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Date getDateFromSample(ActivitySample sample) {
|
private Date getDateFromSample(ActivitySample sample) {
|
||||||
@ -96,15 +103,18 @@ public class SleepAnalysis {
|
|||||||
private final Date sleepEnd;
|
private final Date sleepEnd;
|
||||||
private final long lightSleepDuration;
|
private final long lightSleepDuration;
|
||||||
private final long deepSleepDuration;
|
private final long deepSleepDuration;
|
||||||
|
private final long remSleepDuration;
|
||||||
|
|
||||||
private SleepSession(Date sleepStart,
|
private SleepSession(Date sleepStart,
|
||||||
Date sleepEnd,
|
Date sleepEnd,
|
||||||
long lightSleepDuration,
|
long lightSleepDuration,
|
||||||
long deepSleepDuration) {
|
long deepSleepDuration,
|
||||||
|
long remSleepDuration) {
|
||||||
this.sleepStart = sleepStart;
|
this.sleepStart = sleepStart;
|
||||||
this.sleepEnd = sleepEnd;
|
this.sleepEnd = sleepEnd;
|
||||||
this.lightSleepDuration = lightSleepDuration;
|
this.lightSleepDuration = lightSleepDuration;
|
||||||
this.deepSleepDuration = deepSleepDuration;
|
this.deepSleepDuration = deepSleepDuration;
|
||||||
|
this.remSleepDuration = remSleepDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getSleepStart() {
|
public Date getSleepStart() {
|
||||||
@ -122,5 +132,9 @@ public class SleepAnalysis {
|
|||||||
public long getDeepSleepDuration() {
|
public long getDeepSleepDuration() {
|
||||||
return deepSleepDuration;
|
return deepSleepDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getRemSleepDuration() {
|
||||||
|
return remSleepDuration;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,27 +134,25 @@ public class SleepChartFragment extends AbstractChartFragment {
|
|||||||
|
|
||||||
final long lightSleepDuration = calculateLightSleepDuration(sleepSessions);
|
final long lightSleepDuration = calculateLightSleepDuration(sleepSessions);
|
||||||
final long deepSleepDuration = calculateDeepSleepDuration(sleepSessions);
|
final long deepSleepDuration = calculateDeepSleepDuration(sleepSessions);
|
||||||
|
final long remSleepDuration = calculateRemSleepDuration(sleepSessions);
|
||||||
|
|
||||||
final long totalSeconds = lightSleepDuration + deepSleepDuration;
|
final long totalSeconds = lightSleepDuration + deepSleepDuration + remSleepDuration;
|
||||||
|
|
||||||
final List<PieEntry> entries;
|
final List<PieEntry> entries = new ArrayList<>();
|
||||||
final List<Integer> colors;
|
final List<Integer> colors = new ArrayList<>();
|
||||||
|
|
||||||
if (sleepSessions.isEmpty()) {
|
if (!sleepSessions.isEmpty()) {
|
||||||
entries = Collections.emptyList();
|
entries.add(new PieEntry(lightSleepDuration, getActivity().getString(R.string.abstract_chart_fragment_kind_light_sleep)));
|
||||||
colors = Collections.emptyList();
|
entries.add(new PieEntry(deepSleepDuration, getActivity().getString(R.string.abstract_chart_fragment_kind_deep_sleep)));
|
||||||
} else {
|
colors.add(getColorFor(ActivityKind.TYPE_LIGHT_SLEEP));
|
||||||
entries = Arrays.asList(
|
colors.add(getColorFor(ActivityKind.TYPE_DEEP_SLEEP));
|
||||||
new PieEntry(lightSleepDuration, getActivity().getString(R.string.abstract_chart_fragment_kind_light_sleep)),
|
|
||||||
new PieEntry(deepSleepDuration, getActivity().getString(R.string.abstract_chart_fragment_kind_deep_sleep))
|
if (supportsRemSleep(mGBDevice)) {
|
||||||
);
|
entries.add(new PieEntry(remSleepDuration, getActivity().getString(R.string.abstract_chart_fragment_kind_rem_sleep)));
|
||||||
colors = Arrays.asList(
|
colors.add(getColorFor(ActivityKind.TYPE_REM_SLEEP));
|
||||||
getColorFor(ActivityKind.TYPE_LIGHT_SLEEP),
|
}
|
||||||
getColorFor(ActivityKind.TYPE_DEEP_SLEEP)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
String totalSleep = DateTimeUtils.formatDurationHoursMinutes(totalSeconds, TimeUnit.SECONDS);
|
String totalSleep = DateTimeUtils.formatDurationHoursMinutes(totalSeconds, TimeUnit.SECONDS);
|
||||||
PieDataSet set = new PieDataSet(entries, "");
|
PieDataSet set = new PieDataSet(entries, "");
|
||||||
set.setValueFormatter(new ValueFormatter() {
|
set.setValueFormatter(new ValueFormatter() {
|
||||||
@ -190,6 +188,14 @@ public class SleepChartFragment extends AbstractChartFragment {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private long calculateRemSleepDuration(List<SleepSession> sleepSessions) {
|
||||||
|
long result = 0;
|
||||||
|
for (SleepSession sleepSession : sleepSessions) {
|
||||||
|
result += sleepSession.getRemSleepDuration();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateChartsnUIThread(ChartsData chartsData) {
|
protected void updateChartsnUIThread(ChartsData chartsData) {
|
||||||
MyChartsData mcd = (MyChartsData) chartsData;
|
MyChartsData mcd = (MyChartsData) chartsData;
|
||||||
@ -424,6 +430,14 @@ public class SleepChartFragment extends AbstractChartFragment {
|
|||||||
deepSleepEntry.label = akDeepSleep.label;
|
deepSleepEntry.label = akDeepSleep.label;
|
||||||
deepSleepEntry.formColor = akDeepSleep.color;
|
deepSleepEntry.formColor = akDeepSleep.color;
|
||||||
legendEntries.add(deepSleepEntry);
|
legendEntries.add(deepSleepEntry);
|
||||||
|
|
||||||
|
if (supportsRemSleep(getChartsHost().getDevice())) {
|
||||||
|
LegendEntry remSleepEntry = new LegendEntry();
|
||||||
|
remSleepEntry.label = akRemSleep.label;
|
||||||
|
remSleepEntry.formColor = akRemSleep.color;
|
||||||
|
legendEntries.add(remSleepEntry);
|
||||||
|
}
|
||||||
|
|
||||||
heartRateIcon.setVisibility(View.GONE); //hide heart icon
|
heartRateIcon.setVisibility(View.GONE); //hide heart icon
|
||||||
intensityTotalIcon.setVisibility(View.GONE); //hide intensity icon
|
intensityTotalIcon.setVisibility(View.GONE); //hide intensity icon
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@ import com.github.mikephil.charting.components.Legend;
|
|||||||
import com.github.mikephil.charting.components.LegendEntry;
|
import com.github.mikephil.charting.components.LegendEntry;
|
||||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -66,7 +68,9 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
|||||||
long balance = 0;
|
long balance = 0;
|
||||||
|
|
||||||
for (ActivityAmount amount : activityAmounts.getAmounts()) {
|
for (ActivityAmount amount : activityAmounts.getAmounts()) {
|
||||||
if (amount.getActivityKind() == ActivityKind.TYPE_DEEP_SLEEP || amount.getActivityKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
|
if (amount.getActivityKind() == ActivityKind.TYPE_DEEP_SLEEP ||
|
||||||
|
amount.getActivityKind() == ActivityKind.TYPE_LIGHT_SLEEP ||
|
||||||
|
amount.getActivityKind() == ActivityKind.TYPE_REM_SLEEP) {
|
||||||
balance += amount.getTotalSeconds();
|
balance += amount.getTotalSeconds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,16 +93,24 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
|||||||
float[] getTotalsForActivityAmounts(ActivityAmounts activityAmounts) {
|
float[] getTotalsForActivityAmounts(ActivityAmounts activityAmounts) {
|
||||||
long totalSecondsDeepSleep = 0;
|
long totalSecondsDeepSleep = 0;
|
||||||
long totalSecondsLightSleep = 0;
|
long totalSecondsLightSleep = 0;
|
||||||
|
long totalSecondsRemSleep = 0;
|
||||||
for (ActivityAmount amount : activityAmounts.getAmounts()) {
|
for (ActivityAmount amount : activityAmounts.getAmounts()) {
|
||||||
if (amount.getActivityKind() == ActivityKind.TYPE_DEEP_SLEEP) {
|
if (amount.getActivityKind() == ActivityKind.TYPE_DEEP_SLEEP) {
|
||||||
totalSecondsDeepSleep += amount.getTotalSeconds();
|
totalSecondsDeepSleep += amount.getTotalSeconds();
|
||||||
} else if (amount.getActivityKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
|
} else if (amount.getActivityKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
|
||||||
totalSecondsLightSleep += amount.getTotalSeconds();
|
totalSecondsLightSleep += amount.getTotalSeconds();
|
||||||
|
} else if (amount.getActivityKind() == ActivityKind.TYPE_REM_SLEEP) {
|
||||||
|
totalSecondsRemSleep += amount.getTotalSeconds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int totalMinutesDeepSleep = (int) (totalSecondsDeepSleep / 60);
|
int totalMinutesDeepSleep = (int) (totalSecondsDeepSleep / 60);
|
||||||
int totalMinutesLightSleep = (int) (totalSecondsLightSleep / 60);
|
int totalMinutesLightSleep = (int) (totalSecondsLightSleep / 60);
|
||||||
return new float[]{totalMinutesDeepSleep, totalMinutesLightSleep};
|
int totalMinutesRemSleep = (int) (totalSecondsRemSleep / 60);
|
||||||
|
if (supportsRemSleep(getChartsHost().getDevice())) {
|
||||||
|
return new float[]{totalMinutesDeepSleep, totalMinutesLightSleep, totalMinutesRemSleep};
|
||||||
|
} else {
|
||||||
|
return new float[]{totalMinutesDeepSleep, totalMinutesLightSleep};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -108,7 +120,14 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
String[] getPieLabels() {
|
String[] getPieLabels() {
|
||||||
return new String[]{getString(R.string.abstract_chart_fragment_kind_deep_sleep), getString(R.string.abstract_chart_fragment_kind_light_sleep)};
|
String[] labels = {
|
||||||
|
getString(R.string.abstract_chart_fragment_kind_deep_sleep),
|
||||||
|
getString(R.string.abstract_chart_fragment_kind_light_sleep)
|
||||||
|
};
|
||||||
|
if (supportsRemSleep(getChartsHost().getDevice())) {
|
||||||
|
labels = ArrayUtils.add(labels, getString(R.string.abstract_chart_fragment_kind_rem_sleep));
|
||||||
|
}
|
||||||
|
return labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -143,7 +162,11 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
int[] getColors() {
|
int[] getColors() {
|
||||||
return new int[]{akDeepSleep.color, akLightSleep.color};
|
int[] colors = {akDeepSleep.color, akLightSleep.color};
|
||||||
|
if (supportsRemSleep(getChartsHost().getDevice())) {
|
||||||
|
colors = ArrayUtils.add(colors, akRemSleep.color);
|
||||||
|
}
|
||||||
|
return colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -160,6 +183,13 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
|||||||
deepSleepEntry.formColor = akDeepSleep.color;
|
deepSleepEntry.formColor = akDeepSleep.color;
|
||||||
legendEntries.add(deepSleepEntry);
|
legendEntries.add(deepSleepEntry);
|
||||||
|
|
||||||
|
if (supportsRemSleep(getChartsHost().getDevice())) {
|
||||||
|
LegendEntry remSleepEntry = new LegendEntry();
|
||||||
|
remSleepEntry.label = akRemSleep.label;
|
||||||
|
remSleepEntry.formColor = akRemSleep.color;
|
||||||
|
legendEntries.add(remSleepEntry);
|
||||||
|
}
|
||||||
|
|
||||||
chart.getLegend().setCustom(legendEntries);
|
chart.getLegend().setCustom(legendEntries);
|
||||||
chart.getLegend().setTextColor(LEGEND_TEXT_COLOR);
|
chart.getLegend().setTextColor(LEGEND_TEXT_COLOR);
|
||||||
chart.getLegend().setWordWrapEnabled(true);
|
chart.getLegend().setWordWrapEnabled(true);
|
||||||
|
@ -272,6 +272,11 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsRemSleep() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsWeather() {
|
public boolean supportsWeather() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -33,6 +33,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all sample providers. A Sample provider is device specific and provides
|
* Base class for all sample providers. A Sample provider is device specific and provides
|
||||||
@ -73,10 +74,18 @@ public abstract class AbstractSampleProvider<T extends AbstractActivitySample> i
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<T> getSleepSamples(int timestamp_from, int timestamp_to) {
|
public List<T> getSleepSamples(int timestamp_from, int timestamp_to) {
|
||||||
|
final DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(getDevice());
|
||||||
|
|
||||||
|
// If the device does not support REM sleep, we need to exclude its bit from the activity type
|
||||||
|
int sleepActivityType = ActivityKind.TYPE_SLEEP;
|
||||||
|
if (!coordinator.supportsRemSleep()) {
|
||||||
|
sleepActivityType &= ~ActivityKind.TYPE_REM_SLEEP;
|
||||||
|
}
|
||||||
|
|
||||||
if (getRawKindSampleProperty() != null) {
|
if (getRawKindSampleProperty() != null) {
|
||||||
return getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_SLEEP);
|
return getGBActivitySamples(timestamp_from, timestamp_to, sleepActivityType);
|
||||||
} else {
|
} else {
|
||||||
return getActivitySamplesByActivityFilter(timestamp_from, timestamp_to, ActivityKind.TYPE_SLEEP);
|
return getActivitySamplesByActivityFilter(timestamp_from, timestamp_to, sleepActivityType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,6 +341,11 @@ public interface DeviceCoordinator {
|
|||||||
*/
|
*/
|
||||||
boolean supportsRealtimeData();
|
boolean supportsRealtimeData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the device supports REM sleep tracking.
|
||||||
|
*/
|
||||||
|
boolean supportsRemSleep();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether the device supports current weather and/or weather
|
* Indicates whether the device supports current weather and/or weather
|
||||||
* forecast display.
|
* forecast display.
|
||||||
|
@ -53,10 +53,11 @@ public class ActivityKind {
|
|||||||
public static final int TYPE_STRENGTH_TRAINING = 0x00200000;
|
public static final int TYPE_STRENGTH_TRAINING = 0x00200000;
|
||||||
public static final int TYPE_HIKING = 0x00400000;
|
public static final int TYPE_HIKING = 0x00400000;
|
||||||
public static final int TYPE_CLIMBING = 0x00800000;
|
public static final int TYPE_CLIMBING = 0x00800000;
|
||||||
|
public static final int TYPE_REM_SLEEP = 0x01000000;
|
||||||
|
|
||||||
private static final int TYPES_COUNT = 26;
|
private static final int TYPES_COUNT = 26;
|
||||||
|
|
||||||
public static final int TYPE_SLEEP = TYPE_LIGHT_SLEEP | TYPE_DEEP_SLEEP;
|
public static final int TYPE_SLEEP = TYPE_LIGHT_SLEEP | TYPE_DEEP_SLEEP | TYPE_REM_SLEEP;
|
||||||
public static final int TYPE_ALL = TYPE_ACTIVITY | TYPE_SLEEP | TYPE_NOT_WORN;
|
public static final int TYPE_ALL = TYPE_ACTIVITY | TYPE_SLEEP | TYPE_NOT_WORN;
|
||||||
|
|
||||||
public static int[] mapToDBActivityTypes(int types, SampleProvider provider) {
|
public static int[] mapToDBActivityTypes(int types, SampleProvider provider) {
|
||||||
@ -131,6 +132,9 @@ public class ActivityKind {
|
|||||||
if ((types & ActivityKind.TYPE_STRENGTH_TRAINING) != 0) {
|
if ((types & ActivityKind.TYPE_STRENGTH_TRAINING) != 0) {
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_STRENGTH_TRAINING);
|
result[i++] = provider.toRawActivityKind(TYPE_STRENGTH_TRAINING);
|
||||||
}
|
}
|
||||||
|
if ((types & ActivityKind.TYPE_REM_SLEEP) != 0) {
|
||||||
|
result[i++] = provider.toRawActivityKind(TYPE_REM_SLEEP);
|
||||||
|
}
|
||||||
|
|
||||||
return Arrays.copyOf(result, i);
|
return Arrays.copyOf(result, i);
|
||||||
}
|
}
|
||||||
@ -199,8 +203,8 @@ public class ActivityKind {
|
|||||||
case TYPE_NOT_MEASURED:
|
case TYPE_NOT_MEASURED:
|
||||||
return R.drawable.ic_activity_not_measured;
|
return R.drawable.ic_activity_not_measured;
|
||||||
case TYPE_LIGHT_SLEEP:
|
case TYPE_LIGHT_SLEEP:
|
||||||
return R.drawable.ic_activity_sleep;
|
|
||||||
case TYPE_DEEP_SLEEP:
|
case TYPE_DEEP_SLEEP:
|
||||||
|
case TYPE_REM_SLEEP:
|
||||||
return R.drawable.ic_activity_sleep;
|
return R.drawable.ic_activity_sleep;
|
||||||
case TYPE_RUNNING:
|
case TYPE_RUNNING:
|
||||||
return R.drawable.ic_activity_running;
|
return R.drawable.ic_activity_running;
|
||||||
|
@ -87,22 +87,26 @@ public class DailyTotals {
|
|||||||
long[] sleep = getTotalsSleepForActivityAmounts(amountsSleep);
|
long[] sleep = getTotalsSleepForActivityAmounts(amountsSleep);
|
||||||
long steps = getTotalsStepsForActivityAmounts(amountsSteps);
|
long steps = getTotalsStepsForActivityAmounts(amountsSteps);
|
||||||
|
|
||||||
return new long[]{steps, sleep[0] + sleep[1]};
|
return new long[]{steps, sleep[0] + sleep[1] + sleep[2]};
|
||||||
}
|
}
|
||||||
|
|
||||||
private long[] getTotalsSleepForActivityAmounts(ActivityAmounts activityAmounts) {
|
private long[] getTotalsSleepForActivityAmounts(ActivityAmounts activityAmounts) {
|
||||||
long totalSecondsDeepSleep = 0;
|
long totalSecondsDeepSleep = 0;
|
||||||
long totalSecondsLightSleep = 0;
|
long totalSecondsLightSleep = 0;
|
||||||
|
long totalSecondsRemSleep = 0;
|
||||||
for (ActivityAmount amount : activityAmounts.getAmounts()) {
|
for (ActivityAmount amount : activityAmounts.getAmounts()) {
|
||||||
if (amount.getActivityKind() == ActivityKind.TYPE_DEEP_SLEEP) {
|
if (amount.getActivityKind() == ActivityKind.TYPE_DEEP_SLEEP) {
|
||||||
totalSecondsDeepSleep += amount.getTotalSeconds();
|
totalSecondsDeepSleep += amount.getTotalSeconds();
|
||||||
} else if (amount.getActivityKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
|
} else if (amount.getActivityKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
|
||||||
totalSecondsLightSleep += amount.getTotalSeconds();
|
totalSecondsLightSleep += amount.getTotalSeconds();
|
||||||
|
} else if (amount.getActivityKind() == ActivityKind.TYPE_REM_SLEEP) {
|
||||||
|
totalSecondsRemSleep += amount.getTotalSeconds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
long totalMinutesDeepSleep = (totalSecondsDeepSleep / 60);
|
long totalMinutesDeepSleep = (totalSecondsDeepSleep / 60);
|
||||||
long totalMinutesLightSleep = (totalSecondsLightSleep / 60);
|
long totalMinutesLightSleep = (totalSecondsLightSleep / 60);
|
||||||
return new long[]{totalMinutesDeepSleep, totalMinutesLightSleep};
|
long totalMinutesRemSleep = (totalSecondsRemSleep / 60);
|
||||||
|
return new long[]{totalMinutesDeepSleep, totalMinutesLightSleep, totalMinutesRemSleep};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
<attr name="chart_deep_sleep" format="color" />
|
<attr name="chart_deep_sleep" format="color" />
|
||||||
<attr name="chart_light_sleep" format="color" />
|
<attr name="chart_light_sleep" format="color" />
|
||||||
|
<attr name="chart_rem_sleep" format="color" />
|
||||||
<attr name="chart_activity" format="color" />
|
<attr name="chart_activity" format="color" />
|
||||||
<attr name="chart_not_worn" format="color" />
|
<attr name="chart_not_worn" format="color" />
|
||||||
<attr name="alternate_row_background" format="color" />
|
<attr name="alternate_row_background" format="color" />
|
||||||
|
@ -27,6 +27,9 @@
|
|||||||
<color name="chart_light_sleep_light" type="color">#46acea</color>
|
<color name="chart_light_sleep_light" type="color">#46acea</color>
|
||||||
<color name="chart_light_sleep_dark" type="color">#b6bfff</color>
|
<color name="chart_light_sleep_dark" type="color">#b6bfff</color>
|
||||||
|
|
||||||
|
<color name="chart_rem_sleep_light" type="color">#b6bfff</color>
|
||||||
|
<color name="chart_rem_sleep_dark" type="color">#46acea</color>
|
||||||
|
|
||||||
<color name="chart_activity_light" type="color">#60bd6d</color>
|
<color name="chart_activity_light" type="color">#60bd6d</color>
|
||||||
<color name="chart_activity_dark" type="color">#59b22c</color>
|
<color name="chart_activity_dark" type="color">#59b22c</color>
|
||||||
|
|
||||||
|
@ -737,6 +737,7 @@
|
|||||||
<string name="abstract_chart_fragment_kind_activity">Activity</string>
|
<string name="abstract_chart_fragment_kind_activity">Activity</string>
|
||||||
<string name="abstract_chart_fragment_kind_light_sleep">Light sleep</string>
|
<string name="abstract_chart_fragment_kind_light_sleep">Light sleep</string>
|
||||||
<string name="abstract_chart_fragment_kind_deep_sleep">Deep sleep</string>
|
<string name="abstract_chart_fragment_kind_deep_sleep">Deep sleep</string>
|
||||||
|
<string name="abstract_chart_fragment_kind_rem_sleep">REM sleep</string>
|
||||||
<string name="abstract_chart_fragment_kind_not_worn">Not worn</string>
|
<string name="abstract_chart_fragment_kind_not_worn">Not worn</string>
|
||||||
<string name="you_slept">You slept from %1$s to %2$s</string>
|
<string name="you_slept">You slept from %1$s to %2$s</string>
|
||||||
<string name="you_did_not_sleep">You did not sleep</string>
|
<string name="you_did_not_sleep">You did not sleep</string>
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
<item name="chart_deep_sleep">@color/chart_deep_sleep_light</item>
|
<item name="chart_deep_sleep">@color/chart_deep_sleep_light</item>
|
||||||
<item name="chart_light_sleep">@color/chart_light_sleep_light</item>
|
<item name="chart_light_sleep">@color/chart_light_sleep_light</item>
|
||||||
|
<item name="chart_rem_sleep">@color/chart_rem_sleep_light</item>
|
||||||
<item name="chart_activity">@color/chart_activity_light</item>
|
<item name="chart_activity">@color/chart_activity_light</item>
|
||||||
<item name="chart_not_worn">@color/chart_not_worn_light</item>
|
<item name="chart_not_worn">@color/chart_not_worn_light</item>
|
||||||
<item name="alternate_row_background">@color/alternate_row_background_light</item>
|
<item name="alternate_row_background">@color/alternate_row_background_light</item>
|
||||||
@ -40,6 +41,7 @@
|
|||||||
|
|
||||||
<item name="chart_deep_sleep">@color/chart_deep_sleep_dark</item>
|
<item name="chart_deep_sleep">@color/chart_deep_sleep_dark</item>
|
||||||
<item name="chart_light_sleep">@color/chart_light_sleep_dark</item>
|
<item name="chart_light_sleep">@color/chart_light_sleep_dark</item>
|
||||||
|
<item name="chart_rem_sleep">@color/chart_rem_sleep_dark</item>
|
||||||
<item name="chart_activity">@color/chart_activity_dark</item>
|
<item name="chart_activity">@color/chart_activity_dark</item>
|
||||||
<item name="chart_not_worn">@color/chart_not_worn_dark</item>
|
<item name="chart_not_worn">@color/chart_not_worn_dark</item>
|
||||||
<item name="alternate_row_background">@color/alternate_row_background_dark</item>
|
<item name="alternate_row_background">@color/alternate_row_background_dark</item>
|
||||||
@ -63,6 +65,7 @@
|
|||||||
|
|
||||||
<item name="chart_deep_sleep">@color/chart_deep_sleep_dark</item>
|
<item name="chart_deep_sleep">@color/chart_deep_sleep_dark</item>
|
||||||
<item name="chart_light_sleep">@color/chart_light_sleep_dark</item>
|
<item name="chart_light_sleep">@color/chart_light_sleep_dark</item>
|
||||||
|
<item name="chart_rem_sleep">@color/chart_rem_sleep_dark</item>
|
||||||
<item name="chart_activity">@color/chart_activity_dark</item>
|
<item name="chart_activity">@color/chart_activity_dark</item>
|
||||||
<item name="chart_not_worn">@color/chart_not_worn_dark</item>
|
<item name="chart_not_worn">@color/chart_not_worn_dark</item>
|
||||||
<item name="alternate_row_background">@color/alternate_row_background_dark</item>
|
<item name="alternate_row_background">@color/alternate_row_background_dark</item>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user