Bugfix: voice announcements need to use KM/Miles (instead of m/feet).

Fixes #722.
This commit is contained in:
Dennis Guse
2021-05-03 22:31:11 +02:00
parent 7e6ffbabd2
commit b395c19832
11 changed files with 144 additions and 147 deletions
@@ -54,7 +54,7 @@ import de.dennisguse.opentracks.services.handlers.GpsStatusValue;
import de.dennisguse.opentracks.services.handlers.HandlerServer;
import de.dennisguse.opentracks.services.sensors.AltitudeSumManager;
import de.dennisguse.opentracks.services.sensors.BluetoothRemoteSensorManager;
import de.dennisguse.opentracks.services.tasks.AnnouncementPeriodicTaskFactory;
import de.dennisguse.opentracks.services.tasks.AnnouncementPeriodicTask;
import de.dennisguse.opentracks.services.tasks.PeriodicTaskExecutor;
import de.dennisguse.opentracks.settings.SettingsActivity;
import de.dennisguse.opentracks.stats.TrackStatistics;
@@ -139,7 +139,7 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
handlerServer = new HandlerServer(this);
contentProviderUtils = new ContentProviderUtils(this);
voiceExecutor = new PeriodicTaskExecutor(this, new AnnouncementPeriodicTaskFactory());
voiceExecutor = new PeriodicTaskExecutor(this, new AnnouncementPeriodicTask.Factory());
notificationManager = new TrackRecordingServiceNotificationManager(this);
@@ -23,6 +23,8 @@ import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.util.Log;
import androidx.annotation.NonNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
@@ -135,7 +137,7 @@ public class AnnouncementPeriodicTask implements PeriodicTask {
}
@Override
public void run(TrackRecordingService trackRecordingService) {
public void run(@NonNull TrackRecordingService trackRecordingService) {
if (trackRecordingService == null) {
Log.e(TAG, "TrackRecordingService is null.");
return;
@@ -231,4 +233,18 @@ public class AnnouncementPeriodicTask implements PeriodicTask {
// We don't care about the utterance id. It is supplied here to force onUtteranceCompleted to be called.
tts.speak(announcement, TextToSpeech.QUEUE_FLUSH, null, "not used");
}
/**
* A {@link PeriodicTaskFactory} for text-to-speech announcement periodic task.
*
* @author Rodrigo Damazio
*/
public static class Factory implements PeriodicTaskFactory {
@Override
@NonNull
public PeriodicTask create(Context context) {
return new AnnouncementPeriodicTask(context);
}
}
}
@@ -1,31 +0,0 @@
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package de.dennisguse.opentracks.services.tasks;
import android.content.Context;
/**
* A {@link PeriodicTaskFactory} for text-to-speech announcement periodic task.
*
* @author Rodrigo Damazio
*/
public class AnnouncementPeriodicTaskFactory implements PeriodicTaskFactory {
@Override
public PeriodicTask create(Context context) {
return new AnnouncementPeriodicTask(context);
}
}
@@ -16,6 +16,8 @@
package de.dennisguse.opentracks.services.tasks;
import androidx.annotation.NonNull;
import de.dennisguse.opentracks.services.TrackRecordingService;
/**
@@ -35,7 +37,7 @@ public interface PeriodicTask {
*
* @param trackRecordingService the track recording service
*/
void run(TrackRecordingService trackRecordingService);
void run(@NonNull TrackRecordingService trackRecordingService);
/**
* Shuts down this task and clean up resources.
@@ -17,6 +17,9 @@ package de.dennisguse.opentracks.services.tasks;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import java.time.Duration;
import de.dennisguse.opentracks.R;
@@ -52,14 +55,13 @@ public class PeriodicTaskExecutor {
private boolean metricUnits;
// The next distance for the distance periodic task
private double nextTaskDistance = Double.MAX_VALUE;
private Distance nextTaskDistance = Distance.of(Double.MAX_VALUE);
public PeriodicTaskExecutor(TrackRecordingService trackRecordingService, PeriodicTaskFactory periodicTaskFactory) {
public PeriodicTaskExecutor(@NonNull TrackRecordingService trackRecordingService, PeriodicTaskFactory periodicTaskFactory) {
this.trackRecordingService = trackRecordingService;
this.periodicTaskFactory = periodicTaskFactory;
TASK_FREQUENCY_OFF = Integer.parseInt(trackRecordingService.getBaseContext().getResources().getString(R.string.frequency_off));
TASK_FREQUENCY_OFF = Integer.parseInt(trackRecordingService.getString(R.string.frequency_off));
taskFrequency = TASK_FREQUENCY_OFF;
}
@@ -97,7 +99,7 @@ public class PeriodicTaskExecutor {
timerTaskExecutor.scheduleTask(Duration.ofMinutes(taskFrequency));
} else {
// For distance periodic task
calculateNextTaskDistance();
updateNextTaskDistance();
}
}
@@ -128,59 +130,48 @@ public class PeriodicTaskExecutor {
return;
}
Distance distance = trackStatistics.getTotalDistance();
if (distance.greaterThan(Distance.of(nextTaskDistance))) {
if (trackStatistics.getTotalDistance().greaterThan(nextTaskDistance)) {
periodicTask.run(trackRecordingService);
calculateNextTaskDistance();
updateNextTaskDistance();
}
}
/**
* Sets task frequency.
*
* @param taskFrequency the task frequency
*/
public void setTaskFrequency(int taskFrequency) {
this.taskFrequency = taskFrequency;
restore();
}
/**
* Sets metricUnits.
*
* @param metricUnits true to use metric units
*/
public void setMetricUnits(boolean metricUnits) {
this.metricUnits = metricUnits;
calculateNextTaskDistance();
updateNextTaskDistance();
}
/**
* Calculates the next distance for the distance periodic task.
*/
private void calculateNextTaskDistance() {
private void updateNextTaskDistance() {
if (!trackRecordingService.isRecording() || trackRecordingService.isPaused() || periodicTask == null) {
return;
}
if (!isDistanceFrequency()) {
nextTaskDistance = Distance.of(Double.MAX_VALUE);
Log.d(TAG, "SplitManager: Distance splits disabled.");
return;
}
TrackStatistics trackStatistics = trackRecordingService.getTrackStatistics();
if (trackStatistics == null) {
return;
}
if (!isDistanceFrequency()) {
nextTaskDistance = Double.MAX_VALUE;
Log.d(TAG, "SplitManager: Distance splits disabled.");
return;
}
nextTaskDistance = calculateNextTaskDistance(trackStatistics);
}
double distance = trackStatistics.getTotalDistance().toKM_Miles(metricUnits);
@VisibleForTesting
public Distance calculateNextTaskDistance(TrackStatistics trackStatistics) {
Distance distance = trackStatistics.getTotalDistance();
// The index will be negative since the frequency is negative.
int index = (int) (distance / taskFrequency);
index -= 1;
nextTaskDistance = taskFrequency * index;
Distance announcementInterval = Distance.one(metricUnits).multipliedBy(Math.abs(taskFrequency));
int index = (int) (distance.dividedBy(announcementInterval));
return announcementInterval.multipliedBy(index + 1);
}
/**
@@ -18,6 +18,8 @@ package de.dennisguse.opentracks.services.tasks;
import android.content.Context;
import androidx.annotation.NonNull;
/**
* An interface for classes that can create {@link PeriodicTask}.
*
@@ -30,5 +32,6 @@ interface PeriodicTaskFactory {
*
* @return the task, or null if the task is not supported
*/
@NonNull
PeriodicTask create(Context context);
}