diff --git a/src/main/java/de/dennisguse/opentracks/content/data/Speed.java b/src/main/java/de/dennisguse/opentracks/content/data/Speed.java index 50bb58c46..0ac26d5a5 100644 --- a/src/main/java/de/dennisguse/opentracks/content/data/Speed.java +++ b/src/main/java/de/dennisguse/opentracks/content/data/Speed.java @@ -5,6 +5,7 @@ import androidx.annotation.NonNull; import java.time.Duration; import java.util.Objects; +import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.util.UnitConversions; public class Speed { @@ -25,6 +26,10 @@ public class Speed { return of(Float.parseFloat(speed_mps)); } + public static Speed ofKMH(double speed_kmh) { + return of(Distance.ofKilometer(speed_kmh), Duration.ofHours(1)); + } + public static Speed zero() { return of(0.0); } @@ -42,10 +47,6 @@ public class Speed { return Speed.of(Math.abs(speed1.speed_mps - speed2.speed_mps)); } - - // Anything faster than that (in meters per second) will be considered moving. - private static final double MAX_NO_MOVEMENT_SPEED = 0.224; - private final double speed_mps; private Speed(double speed_mps) { @@ -65,7 +66,7 @@ public class Speed { } public boolean isMoving() { - return !isInvalid() && speed_mps >= MAX_NO_MOVEMENT_SPEED; + return !isInvalid() && greaterThan(PreferencesUtils.getIdleSpeed()); } public boolean lessThan(Speed speed) { diff --git a/src/main/java/de/dennisguse/opentracks/settings/GpsSettingsFragment.java b/src/main/java/de/dennisguse/opentracks/settings/GpsSettingsFragment.java index 6db9a604d..dd2c6f53f 100644 --- a/src/main/java/de/dennisguse/opentracks/settings/GpsSettingsFragment.java +++ b/src/main/java/de/dennisguse/opentracks/settings/GpsSettingsFragment.java @@ -74,5 +74,8 @@ public class GpsSettingsFragment extends PreferenceFragmentCompat { ListPreference recordingGpsAccuracy = findPreference(getString(R.string.recording_gps_accuracy_key)); recordingGpsAccuracy.setEntries(PreferencesUtils.getThresholdHorizontalAccuracyEntries()); + + ListPreference idleSpeed = findPreference(getString(R.string.idle_speed_key)); + idleSpeed.setEntries(PreferencesUtils.getIdleSpeedEntries()); } } diff --git a/src/main/java/de/dennisguse/opentracks/settings/PreferencesUtils.java b/src/main/java/de/dennisguse/opentracks/settings/PreferencesUtils.java index 518ed3f79..79acef13a 100644 --- a/src/main/java/de/dennisguse/opentracks/settings/PreferencesUtils.java +++ b/src/main/java/de/dennisguse/opentracks/settings/PreferencesUtils.java @@ -42,6 +42,7 @@ import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.content.data.DataField; import de.dennisguse.opentracks.content.data.Distance; import de.dennisguse.opentracks.content.data.Layout; +import de.dennisguse.opentracks.content.data.Speed; import de.dennisguse.opentracks.io.file.TrackFileFormat; import de.dennisguse.opentracks.util.CsvConstants; import de.dennisguse.opentracks.util.TrackIconUtils; @@ -448,6 +449,43 @@ public class PreferencesUtils { } + public static Speed getIdleSpeed() { + final float DEFAULT = Float.parseFloat(resources.getString(R.string.idle_speed_default)); + float value = getFloat(R.string.idle_speed_key, DEFAULT); + return Speed.ofKMH(value); + } + + static String[] getIdleSpeedEntries() { + String[] entryValues = resources.getStringArray(R.array.idle_speed_values); + String[] entries = new String[entryValues.length]; + + final float idleSpeedDefault = Float.parseFloat(resources.getString(R.string.idle_speed_default)); + + boolean metricUnits = isMetricUnits(); + + for (int i = 0; i < entryValues.length; i++) { + float value = Float.parseFloat(entryValues[i]); + if (metricUnits) { + if (value == idleSpeedDefault) { + entries[i] = resources.getString(R.string.value_float_kilometer_hour_recommended, value); + } else { + entries[i] = resources.getString(R.string.value_float_kilometer_hour, value); + } + } else { + double valueMPH = Speed.ofKMH(value).toMPH(); + + if (value == idleSpeedDefault) { + entries[i] = resources.getString(R.string.value_float_mile_hour_recommended, valueMPH); + } else { + entries[i] = resources.getString(R.string.value_float_mile_hour, valueMPH); + } + } + } + + return entries; + } + + public static boolean shouldInstantExportAfterWorkout(Context context) { final boolean INSTANT_POST_WORKOUT_EXPORT_DEFAULT = resources.getBoolean(R.bool.post_workout_export_enabled_default); return getBoolean(R.string.post_workout_export_enabled_key, INSTANT_POST_WORKOUT_EXPORT_DEFAULT) && isDefaultExportDirectoryUri(context); diff --git a/src/main/res/values/settings.xml b/src/main/res/values/settings.xml index 4826f0e1f..48e28d1c8 100644 --- a/src/main/res/values/settings.xml +++ b/src/main/res/values/settings.xml @@ -194,6 +194,21 @@ @string/recording_gps_accuracy_poor + idleSpeed + 0.5 + + 0.3 + @string/idle_speed_default + 1 + 1.5 + 2 + 2.5 + 3 + 3.5 + 4 + 5 + + statsRate @string/stats_rate_speed_or_pace_default diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 6e9d81f89..66471d289 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -357,6 +357,7 @@ limitations under the License. Date (local) Number Default track name + Idle speed threshold UI Theme System Day @@ -473,12 +474,16 @@ limitations under the License. %1$d ft (recommended) %1$d km %1$d km/h + %1$.1f km/h + %1$.1f km/h (recommended) %1$d m %1$d m (excellent GPS) %1$d m (poor GPS) %1$d m (recommended) %1$d mi %1$d mi/h + %1$.1f mi/h + %1$.1f mi/h (recommended) %1$d min %1$d s None diff --git a/src/main/res/xml/settings_gps.xml b/src/main/res/xml/settings_gps.xml index 2c661d073..1db357920 100644 --- a/src/main/res/xml/settings_gps.xml +++ b/src/main/res/xml/settings_gps.xml @@ -27,4 +27,10 @@ android:key="@string/recording_gps_accuracy_key" android:title="@string/settings_recording_min_required_accuracy_title" /> + + \ No newline at end of file