From 3815ee6c59aa3e63a8b54bffb9346c8cc63bdb27 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Sat, 23 Apr 2022 12:36:23 +0200 Subject: [PATCH] Voice announcements and Interval: add sub km/miles options. Fixes #1195. --- .../AnnouncementsSettingsFragment.java | 2 +- .../opentracks/settings/PreferencesUtils.java | 8 ++++-- .../ui/intervals/IntervalStatisticsModel.java | 19 +++++++------ .../ui/intervals/IntervalsFragment.java | 28 ++++++++++++------- .../opentracks/util/StringUtils.java | 18 ++++++++---- src/main/res/values/settings.xml | 3 ++ 6 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/main/java/de/dennisguse/opentracks/settings/AnnouncementsSettingsFragment.java b/src/main/java/de/dennisguse/opentracks/settings/AnnouncementsSettingsFragment.java index a27e036a8..c27356089 100644 --- a/src/main/java/de/dennisguse/opentracks/settings/AnnouncementsSettingsFragment.java +++ b/src/main/java/de/dennisguse/opentracks/settings/AnnouncementsSettingsFragment.java @@ -28,6 +28,6 @@ public class AnnouncementsSettingsFragment extends PreferenceFragmentCompat { voiceFrequency.setEntries(PreferencesUtils.getVoiceAnnouncementFrequencyEntries()); ListPreference voiceDistance = findPreference(getString(R.string.voice_announcement_distance_key)); - voiceDistance.setEntries(PreferencesUtils.getVoiceAnnouncementDistanceEntries()); + voiceDistance.setEntries(PreferencesUtils.getVoiceAnnouncementDistanceEntries(getContext())); } } diff --git a/src/main/java/de/dennisguse/opentracks/settings/PreferencesUtils.java b/src/main/java/de/dennisguse/opentracks/settings/PreferencesUtils.java index ff9c9751a..98a4b51ac 100644 --- a/src/main/java/de/dennisguse/opentracks/settings/PreferencesUtils.java +++ b/src/main/java/de/dennisguse/opentracks/settings/PreferencesUtils.java @@ -44,6 +44,7 @@ import de.dennisguse.opentracks.data.models.UnitConversions; import de.dennisguse.opentracks.io.file.TrackFileFormat; import de.dennisguse.opentracks.ui.customRecordingLayout.CsvLayoutUtils; import de.dennisguse.opentracks.ui.customRecordingLayout.Layout; +import de.dennisguse.opentracks.util.StringUtils; import de.dennisguse.opentracks.util.TrackIconUtils; /** @@ -303,7 +304,8 @@ public class PreferencesUtils { /** * @return Result depends on isMetricUnits */ - static String[] getVoiceAnnouncementDistanceEntries() { + @Deprecated //TODO Context should not be used here; requires refactoring of StringUtils. + static String[] getVoiceAnnouncementDistanceEntries(Context context) { String[] values = resources.getStringArray(R.array.voice_announcement_distance_values); String[] options = new String[values.length]; boolean metricUnits = isMetricUnits(); @@ -311,8 +313,8 @@ public class PreferencesUtils { if (resources.getString(R.string.announcement_off).equals(values[i])) { options[i] = resources.getString(R.string.value_off); } else { - int value = Integer.parseInt(values[i]); - options[i] = resources.getString(metricUnits ? R.string.value_integer_kilometer : R.string.value_integer_mile, value); + Distance distance = Distance.one(metricUnits).multipliedBy(Double.parseDouble(values[i])); + options[i] = StringUtils.formatDistance(context, distance, metricUnits, 0); } } return options; diff --git a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsModel.java b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsModel.java index 8e8868877..1f2e1b72c 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsModel.java +++ b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsModel.java @@ -106,7 +106,7 @@ public class IntervalStatisticsModel extends AndroidViewModel { public void update(Track.Id trackId, boolean metricUnits, @Nullable IntervalOption interval) { if (interval == null) { - interval = IntervalOption.OPTION_1; + interval = IntervalOption.DEFAULT; } lastTrackPointId = null; @@ -119,6 +119,8 @@ public class IntervalStatisticsModel extends AndroidViewModel { * Intervals length this view model support. */ public enum IntervalOption { + OPTION_0_1(0.1f), + OPTION_0_5(0.5f), OPTION_1(1), OPTION_2(2), OPTION_3(3), @@ -128,9 +130,11 @@ public class IntervalStatisticsModel extends AndroidViewModel { OPTION_20(20), OPTION_50(50); - private final int multiplier; + static IntervalOption DEFAULT = OPTION_1; - IntervalOption(int multiplier) { + private final double multiplier; + + IntervalOption(double multiplier) { this.multiplier = multiplier; } @@ -140,13 +144,12 @@ public class IntervalStatisticsModel extends AndroidViewModel { .multipliedBy(multiplier); } + public double getMultiplier() { + return multiplier; + } + public boolean sameMultiplier(IntervalOption intervalOption) { return intervalOption != null && this.multiplier == intervalOption.multiplier; } - - @Override - public String toString() { - return "" + multiplier; //TODO Somehow IntervalsFragment relies on a parsable Integer. - } } } diff --git a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalsFragment.java b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalsFragment.java index 485ad60e0..84aa32b74 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalsFragment.java +++ b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalsFragment.java @@ -23,6 +23,7 @@ import de.dennisguse.opentracks.data.ContentProviderUtils; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.databinding.IntervalListViewBinding; import de.dennisguse.opentracks.settings.PreferencesUtils; +import de.dennisguse.opentracks.util.StringUtils; /** * A fragment to display the intervals from recorded track. @@ -95,6 +96,7 @@ public class IntervalsFragment extends Fragment { return viewBinding.getRoot(); } + @Deprecated //TODO This method must be re-implemented. @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); @@ -109,11 +111,10 @@ public class IntervalsFragment extends Fragment { @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { TextView v = (TextView) super.getView(position, convertView, parent); - if (metricUnits) { - v.setText(getContext().getString(R.string.value_integer_kilometer, Integer.parseInt(v.getText().toString()))); - } else { - v.setText(getContext().getString(R.string.value_integer_mile, Integer.parseInt(v.getText().toString()))); - } + + IntervalStatisticsModel.IntervalOption option = getItem(position); + String stringValue = StringUtils.formatDistance(getContext(), option.getDistance(metricUnits), metricUnits, 0); + v.setText(stringValue); return v; } @@ -124,12 +125,19 @@ public class IntervalsFragment extends Fragment { }; viewBinding.intervalsDropdown.setAdapter(intervalsAdapter); - viewBinding.intervalsDropdown.setOnItemClickListener((parent, view1, position, id) -> updateIntervals(metricUnits, IntervalStatisticsModel.IntervalOption.values()[position])); + viewBinding.intervalsDropdown.setOnItemClickListener((parent, view1, position, id) -> { + updateIntervals(metricUnits, IntervalStatisticsModel.IntervalOption.values()[position]); - viewBinding.intervalsDropdown.setText( - getContext().getString(R.string.value_integer_kilometer, Integer.parseInt(selectedInterval != null ? selectedInterval.toString() : IntervalStatisticsModel.IntervalOption.values()[0].toString())), - false - ); + //TODO This duplicates the intervalAdapter code + IntervalStatisticsModel.IntervalOption option = selectedInterval != null ? selectedInterval : IntervalStatisticsModel.IntervalOption.DEFAULT; + String stringValue = StringUtils.formatDistance(getContext(), option.getDistance(metricUnits), metricUnits, 0); + viewBinding.intervalsDropdown.setText(stringValue, false); + }); + + //TODO This duplicates the intervalAdapter code + IntervalStatisticsModel.IntervalOption option = selectedInterval != null ? selectedInterval : IntervalStatisticsModel.IntervalOption.DEFAULT; + String stringValue = StringUtils.formatDistance(getContext(), option.getDistance(metricUnits), metricUnits, 0); + viewBinding.intervalsDropdown.setText(stringValue, false); } @Override diff --git a/src/main/java/de/dennisguse/opentracks/util/StringUtils.java b/src/main/java/de/dennisguse/opentracks/util/StringUtils.java index 83ffb8e36..675ef8ac5 100644 --- a/src/main/java/de/dennisguse/opentracks/util/StringUtils.java +++ b/src/main/java/de/dennisguse/opentracks/util/StringUtils.java @@ -136,11 +136,15 @@ public class StringUtils { * @param metricUnits true to use metric units. False to use imperial units */ public static String formatDistance(Context context, Distance distance, boolean metricUnits) { + return formatDistance(context, distance, metricUnits, 2); + } + + public static String formatDistance(Context context, Distance distance, boolean metricUnits, int decimalCount) { if (distance.isInvalid()) { return context.getString(R.string.value_unknown); } - Pair distanceParts = getDistanceParts(context, distance, metricUnits); + Pair distanceParts = getDistanceParts(context, distance, metricUnits, decimalCount); return context.getString(R.string.distance_with_unit, distanceParts.first, distanceParts.second); } @@ -196,21 +200,25 @@ public class StringUtils { * @return the formatted distance (or null) and it's unit as {@link Pair} */ public static Pair getDistanceParts(Context context, Distance distance, boolean metricUnits) { + return getDistanceParts(context, distance, metricUnits, 2); + } + + public static Pair getDistanceParts(Context context, Distance distance, boolean metricUnits, int decimalCount) { if (distance.isInvalid()) { return new Pair<>(null, context.getString(metricUnits ? R.string.unit_meter : R.string.unit_feet)); } if (metricUnits) { if (distance.greaterThan(Distance.of(500))) { - return new Pair<>(formatDecimal(distance.toKM()), context.getString(R.string.unit_kilometer)); + return new Pair<>(formatDecimal(distance.toKM(), decimalCount), context.getString(R.string.unit_kilometer)); } else { - return new Pair<>(formatDecimal(distance.toM()), context.getString(R.string.unit_meter)); + return new Pair<>(formatDecimal(distance.toM(), decimalCount), context.getString(R.string.unit_meter)); } } else { if (distance.greaterThan(Distance.ofMile(0.5))) { - return new Pair<>(formatDecimal(distance.toMI()), context.getString(R.string.unit_mile)); + return new Pair<>(formatDecimal(distance.toMI(), decimalCount), context.getString(R.string.unit_mile)); } else { - return new Pair<>(formatDecimal(distance.toFT()), context.getString(R.string.unit_feet)); + return new Pair<>(formatDecimal(distance.toFT(), decimalCount), context.getString(R.string.unit_feet)); } } } diff --git a/src/main/res/values/settings.xml b/src/main/res/values/settings.xml index 09efc7cc3..222a41864 100644 --- a/src/main/res/values/settings.xml +++ b/src/main/res/values/settings.xml @@ -265,6 +265,9 @@ @string/announcement_off @string/voice_announcement_distance_default + 0.1 + 0.2 + 0.5 1 5 10