From 3fa589e21c45edca51ff5ca9bed3b46f248122d0 Mon Sep 17 00:00:00 2001 From: y20k Date: Sun, 2 May 2021 17:29:13 +0200 Subject: [PATCH] use smoothed altitude values to get more realistic elevation data (see #99) - v1 (needs testing) --- app/build.gradle | 4 +- app/src/main/java/org/y20k/trackbook/Keys.kt | 3 + .../org/y20k/trackbook/SettingsFragment.kt | 39 ++++++++---- .../java/org/y20k/trackbook/TrackerService.kt | 16 ++--- .../java/org/y20k/trackbook/core/WayPoint.kt | 5 ++ .../y20k/trackbook/helpers/LocationHelper.kt | 62 ++++++++++++++++--- .../trackbook/helpers/PreferencesHelper.kt | 32 +++++++++- .../org/y20k/trackbook/helpers/TrackHelper.kt | 47 ++++++++------ app/src/main/res/drawable/ic_bar_chart_24.xml | 9 +++ app/src/main/res/values/strings.xml | 5 ++ build.gradle | 4 +- 11 files changed, 175 insertions(+), 51 deletions(-) create mode 100644 app/src/main/res/drawable/ic_bar_chart_24.xml diff --git a/app/build.gradle b/app/build.gradle index 8f583cc..5dfeff2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -51,13 +51,13 @@ android { dependencies { // Kotlin - def coroutinesVersion = "1.4.1" + def coroutinesVersion = "1.4.3" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion" // AndroidX - def navigationVersion = "2.3.3" + def navigationVersion = "2.3.5" implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'androidx.core:core-ktx:1.3.2' diff --git a/app/src/main/java/org/y20k/trackbook/Keys.kt b/app/src/main/java/org/y20k/trackbook/Keys.kt index e563f33..fa33abc 100644 --- a/app/src/main/java/org/y20k/trackbook/Keys.kt +++ b/app/src/main/java/org/y20k/trackbook/Keys.kt @@ -56,6 +56,8 @@ object Keys { const val PREF_TRACKING_STATE: String = "prefTrackingState" const val PREF_USE_IMPERIAL_UNITS: String = "prefUseImperialUnits" const val PREF_GPS_ONLY: String = "prefGpsOnly" + const val PREF_RECORDING_ACCURACY_HIGH: String = "prefRecordingAccuracyHigh" + const val PREF_ALTITUDE_SMOOTHING_VALUE: String = "prefAltitudeSmoothingValue" const val PREF_LOCATION_ACCURACY_THRESHOLD: String = "prefLocationAccuracyThreshold" const val PREF_LOCATION_AGE_THRESHOLD: String = "prefLocationAgeThreshold" @@ -106,6 +108,7 @@ object Keys { const val DEFAULT_ACCURACY: Float = 300f // in meters const val DEFAULT_ALTITUDE: Double = 0.0 const val DEFAULT_TIME: Long = 0L + const val DEFAULT_ALTITUDE_SMOOTHING_VALUE: Int = 15 const val DEFAULT_THRESHOLD_LOCATION_ACCURACY: Int = 30 // 30 meters const val DEFAULT_THRESHOLD_LOCATION_AGE: Long = 60000000000L // one minute in nanoseconds const val DEFAULT_THRESHOLD_DISTANCE: Float = 15f // 15 meters diff --git a/app/src/main/java/org/y20k/trackbook/SettingsFragment.kt b/app/src/main/java/org/y20k/trackbook/SettingsFragment.kt index 7aac129..14bf9ca 100644 --- a/app/src/main/java/org/y20k/trackbook/SettingsFragment.kt +++ b/app/src/main/java/org/y20k/trackbook/SettingsFragment.kt @@ -105,15 +105,26 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList return@setOnPreferenceClickListener true } - // set up "Accuracy Threshold" preference - val preferenceAccuracyThreshold: SeekBarPreference = SeekBarPreference(activity as Context) - preferenceAccuracyThreshold.title = getString(R.string.pref_accuracy_threshold_title) - preferenceAccuracyThreshold.setIcon(R.drawable.ic_timeline_24dp) - preferenceAccuracyThreshold.key = Keys.PREF_LOCATION_ACCURACY_THRESHOLD - preferenceAccuracyThreshold.summary = getString(R.string.pref_accuracy_threshold_summary) - preferenceAccuracyThreshold.showSeekBarValue = true - preferenceAccuracyThreshold.max = 50 - preferenceAccuracyThreshold.setDefaultValue(Keys.DEFAULT_THRESHOLD_LOCATION_ACCURACY) + // set up "Recording Accuracy" preference + val preferenceRecordingAccuracy: SwitchPreferenceCompat = SwitchPreferenceCompat(activity as Context) + preferenceRecordingAccuracy.title = getString(R.string.pref_recording_accuracy_title) + preferenceRecordingAccuracy.setIcon(R.drawable.ic_timeline_24dp) + preferenceRecordingAccuracy.key = Keys.PREF_RECORDING_ACCURACY_HIGH + preferenceRecordingAccuracy.summaryOn = getString(R.string.pref_recording_accuracy_summary_high) + preferenceRecordingAccuracy.summaryOff = getString(R.string.pref_recording_accuracy_summary_default) + preferenceRecordingAccuracy.setDefaultValue(false) + + // set up "Altitude Smoothing" preference + val preferenceAltitudeSmoothingValue: SeekBarPreference = SeekBarPreference(activity as Context) + preferenceAltitudeSmoothingValue.title = getString(R.string.pref_altitude_smoothing_value_title) + preferenceAltitudeSmoothingValue.setIcon(R.drawable.ic_bar_chart_24) + preferenceAltitudeSmoothingValue.key = Keys.PREF_ALTITUDE_SMOOTHING_VALUE + preferenceAltitudeSmoothingValue.summary = getString(R.string.pref_altitude_smoothing_value_summary) + preferenceAltitudeSmoothingValue.showSeekBarValue = true + preferenceAltitudeSmoothingValue.min = 5 + preferenceAltitudeSmoothingValue.max = 20 + preferenceAltitudeSmoothingValue.setDefaultValue(Keys.DEFAULT_ALTITUDE_SMOOTHING_VALUE) + // set up "Reset" preference val preferenceResetAdvanced: Preference = Preference(activity as Context) @@ -121,7 +132,9 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList preferenceResetAdvanced.setIcon(R.drawable.ic_undo_24dp) preferenceResetAdvanced.summary = getString(R.string.pref_reset_advanced_summary) preferenceResetAdvanced.setOnPreferenceClickListener{ - preferenceAccuracyThreshold.value = Keys.DEFAULT_THRESHOLD_LOCATION_ACCURACY + // reset "Recording Accuracy" preference + preferenceRecordingAccuracy.isChecked = false + preferenceAltitudeSmoothingValue.value = Keys.DEFAULT_ALTITUDE_SMOOTHING_VALUE return@setOnPreferenceClickListener true } @@ -166,7 +179,8 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList val preferenceCategoryAdvanced: PreferenceCategory = PreferenceCategory(activity as Context) preferenceCategoryAdvanced.title = getString(R.string.pref_advanced_title) - preferenceCategoryAdvanced.contains(preferenceAccuracyThreshold) + preferenceCategoryAdvanced.contains(preferenceRecordingAccuracy) + preferenceCategoryAdvanced.contains(preferenceAltitudeSmoothingValue) preferenceCategoryAdvanced.contains(preferenceResetAdvanced) val preferenceCategoryAbout: PreferenceCategory = PreferenceCategory(context) @@ -182,7 +196,8 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList screen.addPreference(preferenceCategoryMaintenance) screen.addPreference(preferenceDeleteNonStarred) screen.addPreference(preferenceCategoryAdvanced) - screen.addPreference(preferenceAccuracyThreshold) + screen.addPreference(preferenceRecordingAccuracy) + screen.addPreference(preferenceAltitudeSmoothingValue) screen.addPreference(preferenceResetAdvanced) screen.addPreference(preferenceCategoryAbout) screen.addPreference(preferenceAppVersion) diff --git a/app/src/main/java/org/y20k/trackbook/TrackerService.kt b/app/src/main/java/org/y20k/trackbook/TrackerService.kt index 1ebc516..4194e7c 100644 --- a/app/src/main/java/org/y20k/trackbook/TrackerService.kt +++ b/app/src/main/java/org/y20k/trackbook/TrackerService.kt @@ -60,7 +60,8 @@ class TrackerService: Service(), CoroutineScope, SensorEventListener { var networkProviderActive: Boolean = false var useImperial: Boolean = false var gpsOnly: Boolean = false - var locationAccuracyThreshold: Int = Keys.DEFAULT_THRESHOLD_LOCATION_ACCURACY + var accuracyMultiplier: Int = 1 + var altitudeSmoothingValue: Int = Keys.DEFAULT_ALTITUDE_SMOOTHING_VALUE var currentBestLocation: Location = LocationHelper.getDefaultLocation() var lastSave: Date = Keys.DEFAULT_DATE var stepCountOffset: Float = 0f @@ -89,7 +90,8 @@ class TrackerService: Service(), CoroutineScope, SensorEventListener { super.onCreate() gpsOnly = PreferencesHelper.loadGpsOnly(this) useImperial = PreferencesHelper.loadUseImperialUnits(this) - locationAccuracyThreshold = PreferencesHelper.loadAccuracyThreshold(this) + accuracyMultiplier = PreferencesHelper.loadAccuracyMultiplier(this) + altitudeSmoothingValue = PreferencesHelper.loadAltitudeSmoothingValue(this) locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager sensorManager = this.getSystemService(Context.SENSOR_SERVICE) as SensorManager notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager @@ -429,9 +431,9 @@ class TrackerService: Service(), CoroutineScope, SensorEventListener { Keys.PREF_USE_IMPERIAL_UNITS -> { useImperial = PreferencesHelper.loadUseImperialUnits(this@TrackerService) } - // preference "Accuracy Threshold" - Keys.PREF_LOCATION_ACCURACY_THRESHOLD -> { - locationAccuracyThreshold = PreferencesHelper.loadAccuracyThreshold(this@TrackerService) + // preference "Recording Accuracy" + Keys.PREF_RECORDING_ACCURACY_HIGH -> { + accuracyMultiplier = PreferencesHelper.loadAccuracyMultiplier(this@TrackerService) } } } @@ -457,7 +459,7 @@ class TrackerService: Service(), CoroutineScope, SensorEventListener { private val periodicTrackUpdate: Runnable = object : Runnable { override fun run() { // add waypoint to track - step count is continuously updated in onSensorChanged - val result: Pair = TrackHelper.addWayPointToTrack(this@TrackerService, track, currentBestLocation, locationAccuracyThreshold, resumed) + val result: Pair = TrackHelper.addWayPointToTrack(this@TrackerService, track, currentBestLocation, accuracyMultiplier, altitudeSmoothingValue, resumed) // get track from result track = result.first // check if waypoint was successfully added (= result.second) @@ -489,4 +491,4 @@ class TrackerService: Service(), CoroutineScope, SensorEventListener { */ -} \ No newline at end of file +} diff --git a/app/src/main/java/org/y20k/trackbook/core/WayPoint.kt b/app/src/main/java/org/y20k/trackbook/core/WayPoint.kt index 1792909..ff26c50 100644 --- a/app/src/main/java/org/y20k/trackbook/core/WayPoint.kt +++ b/app/src/main/java/org/y20k/trackbook/core/WayPoint.kt @@ -40,6 +40,11 @@ data class WayPoint(@Expose val provider: String, @Expose var isStopOver: Boolean = false, @Expose var starred: Boolean = false): Parcelable { + /* Constructor using just Location */ + constructor(location: Location) : this (location.provider, location.latitude, location.longitude, location. altitude, location.accuracy, location.time) + + /* Constructor using Location plus distanceToStartingPoint and numberSatellites */ + constructor(location: Location, distanceToStartingPoint: Float, numberSatellites: Int) : this (location.provider, location.latitude, location.longitude, location. altitude, location.accuracy, location.time, distanceToStartingPoint, numberSatellites) /* Converts WayPoint into Location */ fun toLocation(): Location { diff --git a/app/src/main/java/org/y20k/trackbook/helpers/LocationHelper.kt b/app/src/main/java/org/y20k/trackbook/helpers/LocationHelper.kt index 302b3b1..dc71c90 100644 --- a/app/src/main/java/org/y20k/trackbook/helpers/LocationHelper.kt +++ b/app/src/main/java/org/y20k/trackbook/helpers/LocationHelper.kt @@ -26,6 +26,7 @@ import android.os.SystemClock import androidx.core.content.ContextCompat import org.y20k.trackbook.Keys import org.y20k.trackbook.core.Track +import org.y20k.trackbook.core.WayPoint import java.util.* import kotlin.math.pow @@ -177,7 +178,7 @@ object LocationHelper { /* Checks if given location is different enough compared to previous location */ - fun isDifferentEnough(previousLocation: Location?, location: Location): Boolean { + fun isDifferentEnough(previousLocation: Location?, location: Location, accuracyMultiplier: Int): Boolean { // check if previous location is (not) available if (previousLocation == null) return true @@ -185,16 +186,15 @@ object LocationHelper { // that the true position is within a circle of this radius. // These formulas determine if the difference between the last point and // new point is statistically significant. - val accuracy = if (location.accuracy != 0.0f) location.accuracy else Keys.DEFAULT_THRESHOLD_DISTANCE - val previousAccuracy = if (previousLocation.accuracy != 0.0f) previousLocation.accuracy else Keys.DEFAULT_THRESHOLD_DISTANCE - val accuracyDelta = Math.sqrt((accuracy.pow(2) + previousAccuracy.pow(2)).toDouble()) - - val distance = calculateDistance(previousLocation, location) + val accuracy: Float = if (location.accuracy != 0.0f) location.accuracy else Keys.DEFAULT_THRESHOLD_DISTANCE + val previousAccuracy: Float = if (previousLocation.accuracy != 0.0f) previousLocation.accuracy else Keys.DEFAULT_THRESHOLD_DISTANCE + val accuracyDelta: Double = Math.sqrt((accuracy.pow(2) + previousAccuracy.pow(2)).toDouble()) + val distance: Float = calculateDistance(previousLocation, location) // With 1*accuracyDelta we have 68% confidence that the points are // different. We can multiply this number to increase confidence but // decrease point recording frequency if needed. - return distance > accuracyDelta + return distance > accuracyDelta * accuracyMultiplier } @@ -211,7 +211,7 @@ object LocationHelper { /* Calculate elevation differences */ - fun calculateElevationDifferences(previousLocation: Location?, location: Location, track: Track): Pair { + fun calculateElevationDifferencesOld(previousLocation: Location?, location: Location, track: Track): Pair { // store current values var positiveElevation: Double = track.positiveElevation var negativeElevation: Double = track.negativeElevation @@ -231,6 +231,27 @@ object LocationHelper { } + /* Calculate elevation differences */ + fun calculateElevationDifferences(previousLocation: Location?, location: Location, track: Track, altitudeSmoothingValue: Int): Pair { + // store current values + var positiveElevation: Double = track.positiveElevation + var negativeElevation: Double = track.negativeElevation + if (previousLocation != null && location.altitude != Keys.DEFAULT_ALTITUDE) { + val locationAltitudeCorrected: Double = calculateCorrectedAltitude(location, track, altitudeSmoothingValue) + val previousLocationAltitudeCorrected: Double = calculateCorrectedAltitude(previousLocation, track, altitudeSmoothingValue) + // get elevation difference and sum it up + val altitudeDifference: Double = locationAltitudeCorrected - previousLocationAltitudeCorrected + if (altitudeDifference > 0) { + positiveElevation = track.positiveElevation + altitudeDifference // upwards movement + } + if (altitudeDifference < 0) { + negativeElevation = track.negativeElevation + altitudeDifference // downwards movement + } + } + return Pair(positiveElevation, negativeElevation) + } + + /* Checks if given location is a stop over */ fun isStopOver(previousLocation: Location?, location: Location): Boolean { if (previousLocation == null) return false @@ -239,4 +260,29 @@ object LocationHelper { } + /* Calculate a moving average taking into account previously recorded altitude values */ + private fun calculateCorrectedAltitude(location: Location, track: Track, altitudeSmoothingValue: Int): Double { + // add location to track + track.wayPoints.add(WayPoint(location)) + // get size of track + val trackSize: Int = track.wayPoints.size + // skip calculation if less than two waypoints available + if (trackSize < 2) return location.altitude + // get number of locations to be used in calculating the moving average + val numberOfLocationsUsedForSmoothing: Int = if (trackSize < altitudeSmoothingValue) { + trackSize + } else { + altitudeSmoothingValue + } + // add altitude values in range and calculate average + val mostRecentWaypointIndex: Int = trackSize - 1 + var altitudeSum: Double = 0.0 + for (i in mostRecentWaypointIndex..(mostRecentWaypointIndex - numberOfLocationsUsedForSmoothing)) { + altitudeSum = altitudeSum + track.wayPoints[i].altitude + } + return altitudeSum / numberOfLocationsUsedForSmoothing + } + + + } diff --git a/app/src/main/java/org/y20k/trackbook/helpers/PreferencesHelper.kt b/app/src/main/java/org/y20k/trackbook/helpers/PreferencesHelper.kt index 1665f63..2c5b60b 100644 --- a/app/src/main/java/org/y20k/trackbook/helpers/PreferencesHelper.kt +++ b/app/src/main/java/org/y20k/trackbook/helpers/PreferencesHelper.kt @@ -98,6 +98,36 @@ object PreferencesHelper { } + + /* Loads state of recording accuracy */ + fun loadRecordingAccuracyHigh(context: Context): Boolean { + // get preferences + val settings = PreferenceManager.getDefaultSharedPreferences(context) + // load current setting + return settings.getBoolean(Keys.PREF_RECORDING_ACCURACY_HIGH, false) + } + + + /* Loads current accuracy multiplier */ + fun loadAccuracyMultiplier(context: Context): Int { + // get preferences + val settings = PreferenceManager.getDefaultSharedPreferences(context) + // load current setting + val recordingAccuracyHigh: Boolean = settings.getBoolean(Keys.PREF_RECORDING_ACCURACY_HIGH, false) + // return multiplier based on state + return if (recordingAccuracyHigh) 2 else 1 + } + + + /* Load altitude smoothing value */ + fun loadAltitudeSmoothingValue(context: Context): Int { + // get preferences + val settings = PreferenceManager.getDefaultSharedPreferences(context) + // load current setting + return settings.getInt(Keys.PREF_ALTITUDE_SMOOTHING_VALUE, Keys.DEFAULT_ALTITUDE_SMOOTHING_VALUE) + } + + /* Loads the state of a map */ fun loadCurrentBestLocation(context: Context): Location { // get preferences @@ -149,4 +179,4 @@ object PreferencesHelper { settings.edit { putBoolean(Keys.PREF_ONE_TIME_HOUSEKEEPING_NECESSARY, state) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/y20k/trackbook/helpers/TrackHelper.kt b/app/src/main/java/org/y20k/trackbook/helpers/TrackHelper.kt index 5f12cac..22c742e 100644 --- a/app/src/main/java/org/y20k/trackbook/helpers/TrackHelper.kt +++ b/app/src/main/java/org/y20k/trackbook/helpers/TrackHelper.kt @@ -20,6 +20,7 @@ package org.y20k.trackbook.helpers import android.content.Context import android.location.Location import android.widget.Toast +import org.y20k.trackbook.Keys import org.y20k.trackbook.R import org.y20k.trackbook.core.Track import org.y20k.trackbook.core.TracklistElement @@ -48,7 +49,7 @@ object TrackHelper { /* Adds given locatiom as waypoint to track */ - fun addWayPointToTrack(context: Context, track: Track, location: Location, locationAccuracyThreshold: Int, resumed: Boolean): Pair { + fun addWayPointToTrack(context: Context, track: Track, location: Location, accuracyMultiplier: Int, altitudeSmoothingValue: Int, resumed: Boolean): Pair { // get previous location val previousLocation: Location? var numberOfWayPoints: Int = track.wayPoints.size @@ -76,8 +77,8 @@ object TrackHelper { // add only if recent and accurate and different val shouldBeAdded: Boolean = (LocationHelper.isRecentEnough(location) && - LocationHelper.isAccurateEnough(location, locationAccuracyThreshold) && - LocationHelper.isDifferentEnough(previousLocation, location)) + LocationHelper.isAccurateEnough(location, Keys.DEFAULT_THRESHOLD_LOCATION_ACCURACY) && + LocationHelper.isDifferentEnough(previousLocation, location, accuracyMultiplier)) // // Debugging for shouldBeAdded - remove for production // val recentEnough: Boolean = LocationHelper.isRecentEnough(location) @@ -98,25 +99,34 @@ object TrackHelper { track.length = track.length + LocationHelper.calculateDistance(previousLocation, location) } - if (location.altitude != 0.0) { - // update altitude values + // update altitude values + val altitude: Double = location.altitude + if (altitude != 0.0) { + + // CASE: First location if (numberOfWayPoints == 0) { - track.maxAltitude = location.altitude - track.minAltitude = location.altitude - } else { - // calculate elevation values (upwards / downwards movements) - val elevationDifferences: Pair = LocationHelper.calculateElevationDifferences(previousLocation, location, track) + track.maxAltitude = altitude + track.minAltitude = altitude + } + + // CASE: Not first location + else { + + // Step 1: Update altitude values + if (altitude > track.maxAltitude) track.maxAltitude = altitude + if (altitude < track.minAltitude) track.minAltitude = altitude + + // Step 2: Calculate and update elevation values (upwards / downwards movements) + val elevationDifferences: Pair = LocationHelper.calculateElevationDifferences(previousLocation, location, track, altitudeSmoothingValue) // check if any differences were calculated if (elevationDifferences != Pair(track.positiveElevation, track.negativeElevation)) { - // update altitude values - if (location.altitude > track.maxAltitude) track.maxAltitude = location.altitude - if (location.altitude < track.minAltitude) track.minAltitude = location.altitude // update elevation values (do not update if resumed -> we do not want to add values calculated during a recording pause) if (!resumed) { track.positiveElevation = elevationDifferences.first track.negativeElevation = elevationDifferences.second } } + } } @@ -126,12 +136,12 @@ object TrackHelper { } // save number of satellites - val numberOfSatellites: Int + val numberSatellites: Int val extras = location.extras if (extras != null && extras.containsKey("satellites")) { - numberOfSatellites = extras.getInt("satellites", 0) + numberSatellites = extras.getInt("satellites", 0) } else { - numberOfSatellites = 0 + numberSatellites = 0 } // add current location as point to center on for later display @@ -139,7 +149,7 @@ object TrackHelper { track.longitude = location.longitude // add location as new waypoint - track.wayPoints.add(WayPoint(provider = location.provider, latitude = location.latitude, longitude = location.longitude, altitude = location.altitude, accuracy = location.accuracy, time = location.time, distanceToStartingPoint = track.length, numberSatellites = numberOfSatellites)) + track.wayPoints.add(WayPoint(location, distanceToStartingPoint = track.length, numberSatellites = numberSatellites)) } return Pair(track, shouldBeAdded) @@ -147,8 +157,7 @@ object TrackHelper { /* Calculates time passed since last stop of recording */ - fun calculateDurationOfPause(recordingStop: Date): Long = - GregorianCalendar.getInstance().time.time - recordingStop.time + fun calculateDurationOfPause(recordingStop: Date): Long = GregorianCalendar.getInstance().time.time - recordingStop.time /* Creates GPX string for given track */ diff --git a/app/src/main/res/drawable/ic_bar_chart_24.xml b/app/src/main/res/drawable/ic_bar_chart_24.xml new file mode 100644 index 0000000..ecbd6ee --- /dev/null +++ b/app/src/main/res/drawable/ic_bar_chart_24.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 09c99ff..2f5b8a8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -78,6 +78,8 @@ App Version Discard location fixes with an accuracy larger than (meters): Accuracy Threshold + Number of waypoints used to smooth the elevation curve. + Altitude Smoothing Advanced Delete all recordings in \"Tracks\" that are not starred. Delete Non-Starred Recordings @@ -89,6 +91,9 @@ Currently using metric units (Kilometer, Meter). Currently using imperial units (Miles, Feet). Use Imperial Measurements + High accuracy. Less waypoints are being recorded. + Default accuracy. + Recording Accuracy Report bugs and suggest improvements on GitHub. Report Issue Reset advanced settings to defaults. diff --git a/build.gradle b/build.gradle index 22a5f08..6faac01 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ buildscript { ext { - kotlin_version = '1.4.31' + kotlin_version = '1.4.32' navigation_version = '2.3.3' } repositories { @@ -10,7 +10,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:4.1.2' + classpath 'com.android.tools.build:gradle:4.1.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigation_version"