Announcements: added current time.

Fixes #1683.
This commit is contained in:
Dennis Guse
2024-12-28 21:01:43 +01:00
parent 01f4359cdf
commit 073b3d2052
9 changed files with 144 additions and 42 deletions
@@ -118,7 +118,13 @@ public class Track {
}
public OffsetDateTime getStartTime() {
return trackStatistics.getStartTime().atOffset(zoneOffset);
return trackStatistics
.getStartTime().atOffset(zoneOffset);
}
public OffsetDateTime getStopTime() {
return trackStatistics
.getStopTime().atOffset(zoneOffset);
}
@NonNull
@@ -22,7 +22,6 @@ import android.media.AudioManager;
import android.media.MediaPlayer;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.text.Spannable;
import android.util.Log;
import androidx.annotation.NonNull;
@@ -118,7 +117,7 @@ public class TTSManager {
}
}
public void announce(@NonNull Spannable announcement) {
public void speak(@NonNull CharSequence announcement) {
synchronized (this) {
if (!ttsReady) {
ttsReady = ttsInitStatus == TextToSpeech.SUCCESS;
@@ -115,7 +115,7 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe
return;
}
voiceAnnouncement.announce(VoiceAnnouncementUtils.createIdle(context));
voiceAnnouncement.speak(VoiceAnnouncementUtils.createIdle(context));
}
public void announceStatisticsIfNeeded(@NonNull Track track) {
@@ -135,7 +135,7 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe
}
if (announce) {
voiceAnnouncement.announce(createAnnouncement(track));
voiceAnnouncement.speak(createAnnouncement(track));
}
}
@@ -155,7 +155,7 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe
sensorStatistics = contentProviderUtils.getSensorStats(track.getId());
}
return VoiceAnnouncementUtils.createStatistics(context, track.getTrackStatistics(), PreferencesUtils.getUnitSystem(), PreferencesUtils.isReportSpeed(track), lastInterval, sensorStatistics);
return VoiceAnnouncementUtils.createStatistics(context, track, PreferencesUtils.getUnitSystem(), PreferencesUtils.isReportSpeed(track), lastInterval, sensorStatistics);
}
public void stop() {
@@ -7,12 +7,14 @@ import static de.dennisguse.opentracks.settings.PreferencesUtils.shouldVoiceAnno
import static de.dennisguse.opentracks.settings.PreferencesUtils.shouldVoiceAnnounceLapPower;
import static de.dennisguse.opentracks.settings.PreferencesUtils.shouldVoiceAnnounceLapSpeedPace;
import static de.dennisguse.opentracks.settings.PreferencesUtils.shouldVoiceAnnounceMovingTime;
import static de.dennisguse.opentracks.settings.PreferencesUtils.shouldVoiceAnnounceTime;
import static de.dennisguse.opentracks.settings.PreferencesUtils.shouldVoiceAnnounceTotalDistance;
import static de.dennisguse.opentracks.settings.PreferencesUtils.shouldVoiceAnnounceUnit;
import android.content.Context;
import android.icu.text.MessageFormat;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.style.TtsSpan;
@@ -20,12 +22,15 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.time.Duration;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Map;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.data.models.Distance;
import de.dennisguse.opentracks.data.models.Power;
import de.dennisguse.opentracks.data.models.Speed;
import de.dennisguse.opentracks.data.models.Track;
import de.dennisguse.opentracks.settings.UnitSystem;
import de.dennisguse.opentracks.stats.SensorStatistics;
import de.dennisguse.opentracks.stats.TrackStatistics;
@@ -42,8 +47,15 @@ class VoiceAnnouncementUtils {
.append(context.getString(R.string.voiceIdle));
}
static Spannable createStatistics(Context context, TrackStatistics trackStatistics, UnitSystem unitSystem, boolean isReportSpeed, @Nullable IntervalStatistics.Interval currentInterval, @Nullable SensorStatistics sensorStatistics) {
static Spannable createStatistics(Context context, Track track, UnitSystem unitSystem, boolean isReportSpeed, @Nullable IntervalStatistics.Interval currentInterval, @Nullable SensorStatistics sensorStatistics) {
TrackStatistics trackStatistics = track.getTrackStatistics();
SpannableStringBuilder builder = new SpannableStringBuilder();
if (shouldVoiceAnnounceTime()) {
appendTime(builder, track.getStopTime());
}
Distance totalDistance = trackStatistics.getTotalDistance();
Speed averageMovingSpeed = trackStatistics.getAverageMovingSpeed();
Speed currentDistancePerTime = currentInterval != null ? currentInterval.getSpeed() : null;
@@ -177,6 +189,7 @@ class VoiceAnnouncementUtils {
return builder;
}
//TODO TtsSpan.TimeBuilder?
private static void appendDuration(@NonNull Context context, @NonNull SpannableStringBuilder builder, @NonNull Duration duration) {
int hours = (int) (duration.toHours());
int minutes = (int) (duration.toMinutes() % 60);
@@ -196,6 +209,20 @@ class VoiceAnnouncementUtils {
}
}
private static void appendTime(@NonNull SpannableStringBuilder builder, OffsetDateTime now) {
TtsSpan.TimeBuilder ttsSpan = new TtsSpan.TimeBuilder();
ttsSpan.setHours(now.getHour());
ttsSpan.setMinutes(now.getMinute());
String formattedTime = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)
.format(now);
Spannable spannable = new SpannableString(formattedTime + ".");
spannable.setSpan(ttsSpan.build(), 0, spannable.length(), SPAN_INCLUSIVE_EXCLUSIVE);
builder.append(spannable);
builder.append(" ");
}
/**
* Speaks as: 98.14 [UNIT] - ninety eight point one four [UNIT with correct plural form]
*
@@ -332,6 +332,10 @@ public class PreferencesUtils {
return getBoolean(R.string.voice_announce_idle_key, true);
}
public static boolean shouldVoiceAnnounceTime() {
return getBoolean(R.string.voice_announce_unit_key, true);
}
public static boolean shouldVoiceAnnounceUnit() {
return getBoolean(R.string.voice_announce_unit_key, true);
}
@@ -46,9 +46,9 @@ public class TrackStatistics {
private final ExtremityMonitor altitudeExtremities = new ExtremityMonitor();
// The track start time.
private Instant startTime;
private Instant startTime; //TODO Should never be null!
// The track stop time.
private Instant stopTime;
private Instant stopTime; //TODO Should never be null!
private Distance totalDistance;
// Updated when new points are received, may be stale.