diff --git a/app/src/main/assets/ic_distance.svg b/app/src/main/assets/ic_distance.svg new file mode 100644 index 000000000..b95d0c897 --- /dev/null +++ b/app/src/main/assets/ic_distance.svg @@ -0,0 +1,70 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummaryDetail.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummaryDetail.java index f719d52d7..b3609f3c4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummaryDetail.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummaryDetail.java @@ -259,8 +259,8 @@ public class ActivitySummaryDetail extends AbstractGBActivity { String activityname = item.getName(); Date starttime = item.getStartTime(); Date endtime = item.getEndTime(); - String starttimeS = DateTimeUtils.formatDateTime(starttime); - String endtimeS = DateTimeUtils.formatDateTime(endtime); + String starttimeS = String.format("%s, %s", DateTimeUtils.formatDate(starttime), DateTimeUtils.formatTime(starttime.getHours(), starttime.getMinutes())); + String endtimeS = String.format("%s, %s", DateTimeUtils.formatDate(endtime), DateTimeUtils.formatTime(endtime.getHours(), endtime.getMinutes())); String durationhms = DateTimeUtils.formatDurationHoursMinutes((endtime.getTime() - starttime.getTime()), TimeUnit.MILLISECONDS); ImageView activity_icon = findViewById(R.id.item_image); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java index 8f9d613fd..922525ebb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java @@ -70,6 +70,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_ import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_STEPS_GOAL; import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_WEIGHT_KG; import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_YEAR_OF_BIRTH; +import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_STEP_LENGTH_CM; public class SettingsActivity extends AbstractSettingsActivity { private static final Logger LOG = LoggerFactory.getLogger(SettingsActivity.class); @@ -459,6 +460,7 @@ public class SettingsActivity extends AbstractSettingsActivity { PREF_USER_WEIGHT_KG, PREF_USER_SLEEP_DURATION, PREF_USER_STEPS_GOAL, + PREF_USER_STEP_LENGTH_CM, "weather_city", }; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityListingAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityListingAdapter.java index 9ccf53736..a9b4106af 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityListingAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityListingAdapter.java @@ -39,10 +39,16 @@ public class ActivityListingAdapter extends AbstractActivityListingAdapter 2000) { + distance = distance / 1000; + unit = "###.#km"; + } + DecimalFormat df = new DecimalFormat(unit); //DecimalFormatSymbols symbols = df.getDecimalFormatSymbols(); //symbols.setGroupingSeparator(' '); - return df.format(item.getDistance()); + return df.format(distance); } @Override @@ -80,6 +86,15 @@ public class ActivityListingAdapter extends AbstractActivityListingAdapter 0) { + return true; + } else { + return false; + } + } + @Override protected int getIcon(StepAnalysis.StepSession item) { int activityKind = item.getActivityKind(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityListingChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityListingChartFragment.java index d53fafe10..b4ab4aef8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityListingChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ActivityListingChartFragment.java @@ -105,7 +105,6 @@ public class ActivityListingChartFragment extends AbstractChartFragment { getChartsHost().enableSwipeRefresh(true); //try to enable pull to refresh, might be needed } else { getChartsHost().enableSwipeRefresh(false); //disable pull to refresh as it collides with swipable view - // this still provides one pull to refresh on the start, in case it is needed } //push to the adapter stepListAdapter.setItems(stepSessions, true); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/StepAnalysis.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/StepAnalysis.java index f549e019b..4129b3296 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/StepAnalysis.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/StepAnalysis.java @@ -30,24 +30,27 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser; public class StepAnalysis { protected static final Logger LOG = LoggerFactory.getLogger(StepAnalysis.class); - final double MULTIPLIER_FEMALE = 0.44; //constants to calculate steps from height - final double MULTIPLIER_OTHER = 0.45; //thes feel too small though - final double MULTIPLIER_MALE = 0.46; - private final double MIN_SESSION_INTENSITY = 0.4; //needs tuning - private double STEP_SIZE = 1; public List calculateStepSessions(List samples) { List result = new ArrayList<>(); + ActivityUser activityUser = new ActivityUser(); + double STEP_LENGTH_M; final int MIN_SESSION_LENGTH = 60 * GBApplication.getPrefs().getInt("chart_list_min_session_length", 5); final int MAX_IDLE_PHASE_LENGTH = 60 * GBApplication.getPrefs().getInt("chart_list_max_idle_phase_length", 5); final int MIN_STEPS_PER_MINUTE = GBApplication.getPrefs().getInt("chart_list_min_steps_per_minute", 40); - final int GENDER = GBApplication.getPrefs().getInt("activity_user_gender", 2); - final int HEIGHT = GBApplication.getPrefs().getInt("activity_user_height_cm", 170); - STEP_SIZE = calculate_step_size(GENDER, HEIGHT); + int stepLengthCm = activityUser.getStepLengthCm(); + int heightCm = activityUser.getHeightCm(); + + if (stepLengthCm == 0 && heightCm != 0) { + STEP_LENGTH_M = heightCm * 0.43 * 0.01; + } else { + STEP_LENGTH_M = stepLengthCm * 0.01; + } + final double MIN_SESSION_INTENSITY = Math.max(0, Math.min(1, MIN_STEPS_PER_MINUTE * 0.01)); ActivitySample previousSample = null; Date sessionStart = null; - Date sessionEnd = null; + Date sessionEnd; int activeSteps = 0; //steps that we count int stepsBetweenActivePeriods = 0; //steps during time when we maybe take a rest but then restart int durationSinceLastActiveStep = 0; @@ -77,7 +80,7 @@ public class StepAnalysis { if (sessionStart == null) { sessionStart = getDateFromSample(sample); activeSteps = sample.getSteps(); - activeIntensity = (int) sample.getIntensity(); + activeIntensity = sample.getIntensity(); heartRateForAverage = heartRateToAdd; activeHrSamplesForAverage = activeHrSamplesToAdd; durationSinceLastActiveStep = 0; @@ -112,7 +115,7 @@ public class StepAnalysis { if (session_length >= MIN_SESSION_LENGTH) { //valid activity session int heartRateAverage = activeHrSamplesForAverage > 0 ? heartRateForAverage / activeHrSamplesForAverage : 0; - float distance = (float) (activeSteps * STEP_SIZE); + float distance = (float) (activeSteps * STEP_LENGTH_M); sessionEnd = new Date((sample.getTimestamp() - durationSinceLastActiveStep) * 1000L); activityKind = detect_activity_kind(session_length, activeSteps, heartRateAverage, activeIntensity); result.add(new StepSession(sessionStart, sessionEnd, activeSteps, heartRateAverage, activeIntensity, distance, activityKind)); @@ -132,7 +135,7 @@ public class StepAnalysis { if (session_length >= MIN_SESSION_LENGTH) { int heartRateAverage = activeHrSamplesForAverage > 0 ? heartRateForAverage / activeHrSamplesForAverage : 0; - float distance = (float) (activeSteps * STEP_SIZE); + float distance = (float) (activeSteps * STEP_LENGTH_M); sessionEnd = getDateFromSample(previousSample); activityKind = detect_activity_kind(session_length, activeSteps, heartRateAverage, activeIntensity); result.add(new StepSession(sessionStart, sessionEnd, activeSteps, heartRateAverage, activeIntensity, distance, activityKind)); @@ -141,22 +144,6 @@ public class StepAnalysis { return result; } - private double calculate_step_size(int gender, int height) { - double multiplier = 0; - switch (gender) { - case ActivityUser.GENDER_MALE: - multiplier = MULTIPLIER_MALE; - break; - case ActivityUser.GENDER_FEMALE: - multiplier = MULTIPLIER_FEMALE; - break; - case ActivityUser.GENDER_OTHER: - multiplier = MULTIPLIER_OTHER; - break; - } - return height * multiplier / 100; - } - private int detect_activity_kind(int session_length, int activeSteps, int heartRateAverage, float intensity) { final int MIN_STEPS_PER_MINUTE_FOR_RUN = GBApplication.getPrefs().getInt("chart_list_min_steps_per_minute_for_run", 120); int spm = (int) (activeSteps / (session_length / 60)); @@ -166,7 +153,7 @@ public class StepAnalysis { if (activeSteps > 200) { return ActivityKind.TYPE_WALKING; } - if (heartRateAverage > 90 && intensity > 30) { //needs tuning + if (heartRateAverage > 90 && intensity > 15) { //needs tuning return ActivityKind.TYPE_EXERCISE; } return ActivityKind.TYPE_ACTIVITY; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AbstractActivityListingAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AbstractActivityListingAdapter.java index 77e628a74..7e622b635 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AbstractActivityListingAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AbstractActivityListingAdapter.java @@ -85,7 +85,7 @@ public abstract class AbstractActivityListingAdapter extends ArrayAdapter LinearLayout hrLayout = view.findViewById(R.id.line_layout_hr); - LinearLayout stepLayout = view.findViewById(R.id.line_layout_step); + LinearLayout distanceLayout = view.findViewById(R.id.line_layout_distance); LinearLayout intensityLayout = view.findViewById(R.id.line_layout_intensity); RelativeLayout parentLayout = view.findViewById(R.id.list_item_parent_layout); @@ -112,6 +112,12 @@ public abstract class AbstractActivityListingAdapter extends ArrayAdapter intensityLayout.setVisibility(View.VISIBLE); } + if (!hasDistance(item)) { + distanceLayout.setVisibility(View.GONE); + } else { + distanceLayout.setVisibility(View.VISIBLE); + } + activityIcon.setImageResource(getIcon(item)); if (position % 2 == 0) { @@ -141,6 +147,8 @@ public abstract class AbstractActivityListingAdapter extends ArrayAdapter protected abstract boolean hasIntensity(T item); + protected abstract boolean hasDistance(T item); + @DrawableRes protected abstract int getIcon(T item); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AbstractItemAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AbstractItemAdapter.java index 0ee5b7d27..284f7002d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AbstractItemAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/AbstractItemAdapter.java @@ -66,23 +66,18 @@ public abstract class AbstractItemAdapter extends ArrayAdapter { } public void setDateFromFilter(long date){ - this.setDateFromFilter(date); } public void setDateToFilter(long date){ - this.setDateToFilter(date); } public void setNameContainsFilter(String name){ - this.setNameContainsFilter(name); } public void setItemsFilter(List items) { - this.setItemsFilter(items); } public void setDeviceFilter(long device) { - this.setDeviceFilter(device); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityUser.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityUser.java index 4d4de0925..9d99e3ab2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityUser.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivityUser.java @@ -44,6 +44,7 @@ public class ActivityUser { private int activityUserCaloriesBurnt; private int activityUserDistanceMeters; private int activityUserActiveTimeMinutes; + private int activityUserStepLengthCm; private static final String defaultUserName = "gadgetbridge-user"; public static final int defaultUserGender = GENDER_FEMALE; @@ -56,6 +57,7 @@ public class ActivityUser { public static final int defaultUserCaloriesBurnt = 2000; public static final int defaultUserDistanceMeters = 5000; public static final int defaultUserActiveTimeMinutes = 60; + public static final int defaultUserStepLengthCm = 0; public static final String PREF_USER_NAME = "mi_user_alias"; public static final String PREF_USER_YEAR_OF_BIRTH = "activity_user_year_of_birth"; @@ -67,6 +69,7 @@ public class ActivityUser { public static final String PREF_USER_CALORIES_BURNT = "activity_user_calories_burnt"; public static final String PREF_USER_DISTANCE_METERS = "activity_user_distance_meters"; public static final String PREF_USER_ACTIVETIME_MINUTES = "activity_user_activetime_minutes"; + public static final String PREF_USER_STEP_LENGTH_CM = "activity_user_step_length_cm"; public ActivityUser() { fetchPreferences(); @@ -97,6 +100,10 @@ public class ActivityUser { return activityUserHeightCm; } + public int getStepLengthCm() { + return activityUserStepLengthCm; + } + /** * @return the user defined sleep duration or the default value when none is set or the stored * value is out of any logical bounds. @@ -139,6 +146,7 @@ public class ActivityUser { activityUserCaloriesBurnt = prefs.getInt(PREF_USER_CALORIES_BURNT, defaultUserCaloriesBurnt); activityUserDistanceMeters = prefs.getInt(PREF_USER_DISTANCE_METERS, defaultUserDistanceMeters); activityUserActiveTimeMinutes = prefs.getInt(PREF_USER_ACTIVETIME_MINUTES, defaultUserActiveTimeMinutes); + activityUserStepLengthCm = prefs.getInt(PREF_USER_STEP_LENGTH_CM, defaultUserStepLengthCm); } public Date getUserBirthday() { diff --git a/app/src/main/res/drawable/ic_activity_unknown_small.xml b/app/src/main/res/drawable/ic_activity_unknown_small.xml index eef0e7d63..63cea871d 100644 --- a/app/src/main/res/drawable/ic_activity_unknown_small.xml +++ b/app/src/main/res/drawable/ic_activity_unknown_small.xml @@ -1,15 +1,4 @@ - - - + + + diff --git a/app/src/main/res/drawable/ic_distance.xml b/app/src/main/res/drawable/ic_distance.xml new file mode 100644 index 000000000..38a179ace --- /dev/null +++ b/app/src/main/res/drawable/ic_distance.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_filter_alt.xml b/app/src/main/res/drawable/ic_filter_alt.xml index 113833ab0..433795746 100644 --- a/app/src/main/res/drawable/ic_filter_alt.xml +++ b/app/src/main/res/drawable/ic_filter_alt.xml @@ -1,10 +1,3 @@ - - + + diff --git a/app/src/main/res/drawable/ic_filter_alt_plus.xml b/app/src/main/res/drawable/ic_filter_alt_plus.xml index 3e4b82c91..ac5f393d4 100644 --- a/app/src/main/res/drawable/ic_filter_alt_plus.xml +++ b/app/src/main/res/drawable/ic_filter_alt_plus.xml @@ -1,16 +1,4 @@ - - - + + + diff --git a/app/src/main/res/drawable/ic_heartrate.xml b/app/src/main/res/drawable/ic_heartrate.xml index 4b61288b4..74a29cffb 100644 --- a/app/src/main/res/drawable/ic_heartrate.xml +++ b/app/src/main/res/drawable/ic_heartrate.xml @@ -1,14 +1,4 @@ - - - + + + diff --git a/app/src/main/res/drawable/ic_intensity.xml b/app/src/main/res/drawable/ic_intensity.xml index 0ec3b9953..d704ad81c 100644 --- a/app/src/main/res/drawable/ic_intensity.xml +++ b/app/src/main/res/drawable/ic_intensity.xml @@ -1,15 +1,4 @@ - - - + + + diff --git a/app/src/main/res/drawable/ic_place.xml b/app/src/main/res/drawable/ic_place.xml deleted file mode 100644 index bb1f75229..000000000 --- a/app/src/main/res/drawable/ic_place.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_shoe.xml b/app/src/main/res/drawable/ic_shoe.xml index eb4d7e539..687dd8104 100644 --- a/app/src/main/res/drawable/ic_shoe.xml +++ b/app/src/main/res/drawable/ic_shoe.xml @@ -1,10 +1,3 @@ - - + + diff --git a/app/src/main/res/layout/activity_list_item.xml b/app/src/main/res/layout/activity_list_item.xml index 243b0e107..eafeaddcd 100644 --- a/app/src/main/res/layout/activity_list_item.xml +++ b/app/src/main/res/layout/activity_list_item.xml @@ -172,7 +172,7 @@ android:layout_height="20dp" android:layout_gravity="start" android:contentDescription="@string/candidate_item_device_image" - app:srcCompat="@drawable/ic_place" /> + app:srcCompat="@drawable/ic_distance" /> Gender Height in cm Weight in kg + Step length in cm Charts Settings Enable left/right swipe in the charts activity diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index a53e4b286..761e87627 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -136,6 +136,12 @@ android:maxLength="3" android:title="@string/activity_prefs_weight_kg" /> + +