From 5be4c107f4f09a486cf9d1f2fb4671ba26ce53f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n?= Date: Thu, 27 Aug 2020 17:50:13 +0200 Subject: [PATCH] Announcement: while recording report current interval pace or speed. Fixes #134. --- .../util/AnnouncementUtilsTest.java | 51 ++++++++++++++++++- .../provider/ContentProviderUtils.java | 2 +- .../tasks/AnnouncementPeriodicTask.java | 14 ++++- .../opentracks/util/AnnouncementUtils.java | 21 +++++++- .../viewmodels/IntervalStatistics.java | 10 ++-- src/main/res/values-es/strings.xml | 4 ++ src/main/res/values/strings.xml | 4 ++ 7 files changed, 98 insertions(+), 8 deletions(-) diff --git a/src/androidTest/java/de/dennisguse/opentracks/util/AnnouncementUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/util/AnnouncementUtilsTest.java index c826ec62a..cda4c40b6 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/util/AnnouncementUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/util/AnnouncementUtilsTest.java @@ -9,7 +9,15 @@ import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.Arrays; +import java.util.List; + +import de.dennisguse.opentracks.R; +import de.dennisguse.opentracks.content.data.TestDataUtil; +import de.dennisguse.opentracks.content.data.Track; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.viewmodels.IntervalStatistics; @RunWith(AndroidJUnit4.class) public class AnnouncementUtilsTest { @@ -26,9 +34,50 @@ public class AnnouncementUtilsTest { stats.setTotalElevationGain(6000); // when - String announcement = AnnouncementUtils.getAnnouncement(context, stats, "airplane"); + String announcement = AnnouncementUtils.getAnnouncement(context, stats, "airplane", null); // then Assert.assertEquals("OpenTracks total distance 20.00 kilometers in 5 minutes 0 seconds at 240.0 kilometers per hour", announcement); } + + @Test + public void getAnnouncement_withInterval() { + TrackStatistics stats = new TrackStatistics(); + stats.setTotalDistance(20000); + stats.setTotalTime(600000); + stats.setMovingTime(300000); + stats.setMaxSpeed(100); + stats.setTotalElevationGain(6000); + + IntervalStatistics intervalStatistics = new IntervalStatistics(); + List trackPoints = Arrays.asList(TestDataUtil.createTrack(new Track.Id(System.currentTimeMillis()), 10).second); + intervalStatistics.build(trackPoints, 1000); + IntervalStatistics.Interval lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); + + int speedId = R.plurals.voiceSpeedKilometersPerHour; + double kmPerHour = lastInterval.getSpeed_ms() * UnitConversions.MPS_TO_KMH; + + String firstPartMsg = "OpenTracks total distance 20.00 kilometers in 5 minutes 0 seconds at 240.0 kilometers per hour"; + String rateMsg = " With a current kilometer speed of " + context.getResources().getQuantityString(speedId, getQuantityCount(kmPerHour), kmPerHour); + String msg = firstPartMsg + rateMsg; + + // when + String announcement = AnnouncementUtils.getAnnouncement(context, stats, "airplane", lastInterval); + + // then + Assert.assertEquals(msg, announcement); + } + + private int getQuantityCount(double d) { + if (d == 0) { + return 0; + } else if (d == 1) { + return 1; + } else if (d == 2) { + return 2; + } else { + int count = (int) d; + return Math.max(count, 3); + } + } } \ No newline at end of file diff --git a/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java b/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java index dfd8c60e8..b58f24973 100644 --- a/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java +++ b/src/main/java/de/dennisguse/opentracks/content/provider/ContentProviderUtils.java @@ -836,7 +836,7 @@ public class ContentProviderUtils { /** * Creates the {@link ContentValues} for a {@link TrackPoint}. * - * @param trackPoint the trackPoint + * @param trackPoint the trackPointstats_pace_km#87 * @param trackId the track id */ private ContentValues createContentValues(TrackPoint trackPoint, Track.Id trackId) { diff --git a/src/main/java/de/dennisguse/opentracks/services/tasks/AnnouncementPeriodicTask.java b/src/main/java/de/dennisguse/opentracks/services/tasks/AnnouncementPeriodicTask.java index 75b2f2c91..65f0ee203 100644 --- a/src/main/java/de/dennisguse/opentracks/services/tasks/AnnouncementPeriodicTask.java +++ b/src/main/java/de/dennisguse/opentracks/services/tasks/AnnouncementPeriodicTask.java @@ -22,14 +22,18 @@ import android.speech.tts.TextToSpeech; import android.speech.tts.UtteranceProgressListener; import android.util.Log; +import java.util.List; import java.util.Locale; import de.dennisguse.opentracks.content.data.Track; +import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.provider.ContentProviderUtils; import de.dennisguse.opentracks.services.TrackRecordingService; import de.dennisguse.opentracks.stats.TrackStatistics; import de.dennisguse.opentracks.util.AnnouncementUtils; import de.dennisguse.opentracks.util.PreferencesUtils; +import de.dennisguse.opentracks.util.UnitConversions; +import de.dennisguse.opentracks.viewmodels.IntervalStatistics; /** * This class will periodically announce the user's {@link TrackStatistics}. @@ -159,9 +163,17 @@ public class AnnouncementPeriodicTask implements PeriodicTask { Log.i(TAG, "Speech is not allowed at this time."); return; } + Track track = contentProviderUtils.getTrack(PreferencesUtils.getRecordingTrackId(context)); String category = track != null ? track.getCategory() : ""; - String announcement = AnnouncementUtils.getAnnouncement(context, trackStatistics, category); + + List trackPoints = contentProviderUtils.getTrackPoints(track.getId()); + IntervalStatistics intervalStatistics = new IntervalStatistics(); + intervalStatistics.build(trackPoints, (float) (PreferencesUtils.isMetricUnits(context) ? 1 * UnitConversions.KM_TO_M : 1 * UnitConversions.MI_TO_M)); + int numIntervals = intervalStatistics.getIntervalList().size(); + IntervalStatistics.Interval lastInterval = numIntervals > 0 ? intervalStatistics.getIntervalList().get(numIntervals - 1) : null; + + String announcement = AnnouncementUtils.getAnnouncement(context, trackStatistics, category, lastInterval); speakAnnouncement(announcement); } diff --git a/src/main/java/de/dennisguse/opentracks/util/AnnouncementUtils.java b/src/main/java/de/dennisguse/opentracks/util/AnnouncementUtils.java index e7a82b52d..d960c20e2 100644 --- a/src/main/java/de/dennisguse/opentracks/util/AnnouncementUtils.java +++ b/src/main/java/de/dennisguse/opentracks/util/AnnouncementUtils.java @@ -2,18 +2,22 @@ package de.dennisguse.opentracks.util; import android.content.Context; +import androidx.annotation.Nullable; + import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.viewmodels.IntervalStatistics; public class AnnouncementUtils { private AnnouncementUtils() {} - public static String getAnnouncement(Context context, TrackStatistics trackStatistics, String category) { + public static String getAnnouncement(Context context, TrackStatistics trackStatistics, String category, @Nullable IntervalStatistics.Interval currentInterval) { boolean metricUnits = PreferencesUtils.isMetricUnits(context); boolean reportSpeed = PreferencesUtils.isReportSpeed(context, category); double distance = trackStatistics.getTotalDistance() * UnitConversions.M_TO_KM; double distancePerTime = trackStatistics.getAverageMovingSpeed() * UnitConversions.MPS_TO_KMH; + double currentDistancePerTime = currentInterval != null ? currentInterval.getSpeed_ms() * UnitConversions.MPS_TO_KMH : 0; if (distance == 0) { return context.getString(R.string.voice_total_distance_zero); @@ -22,23 +26,36 @@ public class AnnouncementUtils { if (!metricUnits) { distance *= UnitConversions.KM_TO_MI; distancePerTime *= UnitConversions.KM_TO_MI; + currentDistancePerTime *= UnitConversions.KM_TO_MI; } String rate; + String currentRate; + String currentRateMsg = ""; if (reportSpeed) { int speedId = metricUnits ? R.plurals.voiceSpeedKilometersPerHour : R.plurals.voiceSpeedMilesPerHour; rate = context.getResources().getQuantityString(speedId, getQuantityCount(distancePerTime), distancePerTime); + + currentRate = context.getResources().getQuantityString(speedId, getQuantityCount(currentDistancePerTime), currentDistancePerTime); + currentRateMsg = metricUnits ? context.getString(R.string.voice_speed_current_kilometer, currentRate) : context.getString(R.string.voice_speed_current_mile, currentRate); } else { double timePerDistance = distancePerTime == 0 ? 0.0 : 1 / distancePerTime; int paceId = metricUnits ? R.string.voice_pace_per_kilometer : R.string.voice_pace_per_mile; long time = Math.round(timePerDistance * UnitConversions.HR_TO_MIN * UnitConversions.MIN_TO_S * UnitConversions.S_TO_MS); rate = context.getString(paceId, getAnnounceTime(context, time)); + + double currentTimePerDistance = currentDistancePerTime == 0 ? 0.0 : 1 / currentDistancePerTime; + long currentTime = Math.round(currentTimePerDistance * UnitConversions.HR_TO_MIN * UnitConversions.MIN_TO_S * UnitConversions.S_TO_MS); + currentRate = context.getString(paceId, getAnnounceTime(context, currentTime)); + currentRateMsg = metricUnits ? context.getString(R.string.voice_pace_current_kilometer, currentRate) : context.getString(R.string.voice_pace_current_mile, currentRate); } int totalDistanceId = metricUnits ? R.plurals.voiceTotalDistanceKilometers : R.plurals.voiceTotalDistanceMiles; String totalDistance = context.getResources().getQuantityString(totalDistanceId, getQuantityCount(distance), distance); - return context.getString(R.string.voice_template, totalDistance, getAnnounceTime(context, trackStatistics.getMovingTime()), rate); + currentRateMsg = currentInterval == null ? "" : " " + currentRateMsg; + + return context.getString(R.string.voice_template, totalDistance, getAnnounceTime(context, trackStatistics.getMovingTime()), rate) + currentRateMsg; } private static String getAnnounceTime(Context context, long time) { diff --git a/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatistics.java b/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatistics.java index 8ce33e02e..490021e2a 100644 --- a/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatistics.java +++ b/src/main/java/de/dennisguse/opentracks/viewmodels/IntervalStatistics.java @@ -10,7 +10,11 @@ import de.dennisguse.opentracks.util.UnitConversions; public class IntervalStatistics { List intervalList = new ArrayList<>(); - public void build(List trackPointList, float distanceInterval) { + /** + * @param trackPointList the list of TrackPoint. + * @param distanceInterval_m the meters of every interval. + */ + public void build(List trackPointList, float distanceInterval_m) { intervalList.clear(); if (trackPointList == null || trackPointList.size() == 0) { @@ -26,8 +30,8 @@ public class IntervalStatistics { interval.distance_m += prevTrackPoint.distanceTo(trackPoint); interval.time_ms += trackPoint.getTime() - prevTrackPoint.getTime(); - if (interval.distance_m >= distanceInterval) { - float adjustFactor = distanceInterval / interval.distance_m; + if (interval.distance_m >= distanceInterval_m) { + float adjustFactor = distanceInterval_m / interval.distance_m; Interval adjustedInterval = new Interval(interval); adjustedInterval.adjust(adjustFactor); diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index bb0e4993a..face34831 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -497,6 +497,10 @@ g) haz lo que creas que ayude a OpenTracks. 2 millas por hora 0 millas por hora OpenTracks de %1$s en %2$s a %3$s + Con una velocidad del kilómetro actual de %1$s + Con una velocidad de la milla actual de %1$s + Con un ritmo del kilómetro actual de %1$s + Con un ritmo de la milla actual de %1$s distancia total de %1$.2f kilómetros distancia total de %1$.2f kilómetros distancia total de 1 kilómetro diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 17379ff5e..285d65b44 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -521,6 +521,10 @@ limitations under the License. 2 miles per hour 0 miles per hour OpenTracks %1$s in %2$s at %3$s + With a current kilometer speed of %1$s + With a current mile speed of %1$s + With a current kilometer pace of %1$s + With a current mile pace of %1$s total distance %1$.2f kilometers total distance %1$.2f kilometers total distance 1 kilometer