forked from upstream-mirrors/OpenTracks
Announcements: can be triggered by time and distance (instead of either).
Fixes #921.
This commit is contained in:
@@ -73,7 +73,7 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
|
||||
public static final RecordingData NOT_RECORDING = new RecordingData(null, null, null);
|
||||
public static final GpsStatusValue STATUS_GPS_DEFAULT = GpsStatusValue.GPS_NONE;
|
||||
|
||||
// The following variables are set in onCreate:
|
||||
// The following variables are setFrequency in onCreate:
|
||||
private VoiceAnnouncementManager voiceAnnouncementManager;
|
||||
private TrackRecordingServiceNotificationManager notificationManager;
|
||||
|
||||
@@ -104,20 +104,21 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
|
||||
Context context = TrackRecordingService.this;
|
||||
if (PreferencesUtils.isKey(context, R.string.stats_units_key, key)) {
|
||||
boolean metricUnits = PreferencesUtils.isMetricUnits(sharedPreferences, context);
|
||||
voiceAnnouncementManager.setMetricUnits(metricUnits);
|
||||
notificationManager.setMetricUnits(metricUnits);
|
||||
}
|
||||
if (PreferencesUtils.isKey(context, R.string.voice_frequency_key, key)) {
|
||||
voiceAnnouncementManager.setTaskFrequency(PreferencesUtils.getVoiceFrequency(sharedPreferences, context));
|
||||
if (PreferencesUtils.isKey(context, R.string.voice_announcement_frequency_key, key)) {
|
||||
voiceAnnouncementManager.setFrequency(PreferencesUtils.getVoiceAnnouncementFrequency(sharedPreferences, context));
|
||||
}
|
||||
if (PreferencesUtils.isKey(context, new int[]{R.string.voice_announcement_distance_key, R.string.stats_units_key}, key)) {
|
||||
voiceAnnouncementManager.setFrequency(PreferencesUtils.getVoiceAnnouncementDistance(sharedPreferences, context));
|
||||
}
|
||||
|
||||
|
||||
trackPointCreator.onSharedPreferenceChanged(sharedPreferences, key);
|
||||
trackRecordingManager.onSharedPreferenceChanged(sharedPreferences, key);
|
||||
}
|
||||
};
|
||||
|
||||
// The following variables are set when recording:
|
||||
// The following variables are setFrequency when recording:
|
||||
private WakeLock wakeLock;
|
||||
|
||||
private final Binder binder = new Binder();
|
||||
|
||||
+38
-61
@@ -40,48 +40,35 @@ public class VoiceAnnouncementManager {
|
||||
|
||||
private final TrackRecordingService trackRecordingService;
|
||||
|
||||
private final int TASK_FREQUENCY_OFF;
|
||||
/**
|
||||
* The task frequency.
|
||||
* A positive value is a time frequency (minutes).
|
||||
* A negative value is a distance frequency (km or mi).
|
||||
* A zero value is to turn off periodic task.
|
||||
*/
|
||||
private int taskFrequency;
|
||||
|
||||
private VoiceAnnouncement voiceAnnouncement;
|
||||
|
||||
private boolean metricUnits;
|
||||
|
||||
private TrackStatistics trackStatistics;
|
||||
|
||||
private static final Distance DISTANCE_OFF = Distance.of(Double.MAX_VALUE);
|
||||
private Distance distanceFrequency = DISTANCE_OFF;
|
||||
@NonNull
|
||||
private Distance nextTotalDistance = DISTANCE_OFF;
|
||||
|
||||
private static final Duration TOTALTIME_OFF = Duration.ofMillis(Long.MAX_VALUE);
|
||||
private Duration totalTimeFrequency = TOTALTIME_OFF;
|
||||
@NonNull
|
||||
private Duration nextTotalTime = TOTALTIME_OFF;
|
||||
|
||||
public VoiceAnnouncementManager(@NonNull TrackRecordingService trackRecordingService) {
|
||||
this.trackRecordingService = trackRecordingService;
|
||||
|
||||
TASK_FREQUENCY_OFF = Integer.parseInt(trackRecordingService.getString(R.string.frequency_off));
|
||||
taskFrequency = TASK_FREQUENCY_OFF;
|
||||
}
|
||||
|
||||
public void restore(@Nullable TrackStatistics trackStatistics) {
|
||||
if (taskFrequency == TASK_FREQUENCY_OFF) {
|
||||
Log.d(TAG, "Task frequency is off.");
|
||||
return;
|
||||
}
|
||||
|
||||
voiceAnnouncement = new VoiceAnnouncement(trackRecordingService);
|
||||
voiceAnnouncement.start();
|
||||
|
||||
if (isTimeFrequency()) {
|
||||
nextTotalTime = trackStatistics != null ? calculateNextDuration(trackStatistics) : TOTALTIME_OFF;
|
||||
} else {
|
||||
// For distance periodic task
|
||||
updateNextTaskDistance(trackStatistics);
|
||||
this.trackStatistics = trackStatistics;
|
||||
|
||||
if (!totalTimeFrequency.isZero()) {
|
||||
nextTotalTime = calculateNextDuration();
|
||||
}
|
||||
if (!distanceFrequency.isZero()) {
|
||||
nextTotalDistance = calculateNextTaskDistance();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,14 +77,15 @@ public class VoiceAnnouncementManager {
|
||||
Log.e(TAG, "Cannot update when in status shutdown.");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean announce = false;
|
||||
this.trackStatistics = track.getTrackStatistics();
|
||||
if (trackStatistics.getTotalDistance().greaterThan(nextTotalDistance)) {
|
||||
updateNextTaskDistance(trackStatistics);
|
||||
nextTotalDistance = calculateNextTaskDistance();
|
||||
announce = true;
|
||||
}
|
||||
if (!trackStatistics.getTotalTime().minus(nextTotalTime).isNegative()) {
|
||||
nextTotalTime = calculateNextDuration(trackStatistics);
|
||||
nextTotalTime = calculateNextDuration();
|
||||
announce = true;
|
||||
}
|
||||
|
||||
@@ -113,59 +101,48 @@ public class VoiceAnnouncementManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void setTaskFrequency(int taskFrequency) {
|
||||
this.taskFrequency = taskFrequency;
|
||||
public void setFrequency(Duration frequency) {
|
||||
this.totalTimeFrequency = frequency;
|
||||
restore(this.trackStatistics);
|
||||
}
|
||||
|
||||
public void setMetricUnits(boolean metricUnits) {
|
||||
this.metricUnits = metricUnits;
|
||||
updateNextTaskDistance(this.trackStatistics);
|
||||
}
|
||||
|
||||
private void updateNextTaskDistance(TrackStatistics trackStatistics) {
|
||||
if (!isDistanceFrequency()) {
|
||||
nextTotalDistance = DISTANCE_OFF;
|
||||
Log.d(TAG, "SplitManager: Distance splits disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (trackStatistics == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
nextTotalDistance = calculateNextTaskDistance(trackStatistics);
|
||||
public void setFrequency(Distance frequency) {
|
||||
this.distanceFrequency = frequency;
|
||||
restore(this.trackStatistics);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public Distance calculateNextTaskDistance(@NonNull TrackStatistics trackStatistics) {
|
||||
public Distance calculateNextTaskDistance() {
|
||||
if (trackStatistics == null) {
|
||||
return DISTANCE_OFF;
|
||||
}
|
||||
|
||||
Distance distance = trackStatistics.getTotalDistance();
|
||||
|
||||
Distance announcementInterval = Distance.one(metricUnits).multipliedBy(Math.abs(taskFrequency));
|
||||
int index = (int) (distance.dividedBy(announcementInterval));
|
||||
return announcementInterval.multipliedBy(index + 1);
|
||||
int index = (int) (distance.dividedBy(distanceFrequency));
|
||||
return distanceFrequency.multipliedBy(index + 1);
|
||||
}
|
||||
|
||||
private Duration calculateNextDuration(@Nullable TrackStatistics trackStatistics) {
|
||||
private Duration calculateNextDuration() {
|
||||
if (trackStatistics == null) {
|
||||
return null;
|
||||
return TOTALTIME_OFF;
|
||||
}
|
||||
|
||||
if (!isTimeFrequency()) {
|
||||
throw new RuntimeException("Using distance frequency as time frequency is impossible.");
|
||||
}
|
||||
Duration totalTime = trackStatistics.getTotalTime();
|
||||
Duration interval = Duration.ofMinutes(taskFrequency);
|
||||
Duration intervalMod = Duration.ofMillis(trackStatistics.getTotalTime().toMillis() % interval.toMillis());
|
||||
Duration intervalMod = Duration.ofMillis(trackStatistics.getTotalTime().toMillis() % totalTimeFrequency.toMillis());
|
||||
|
||||
return totalTime.plus(interval.minus(intervalMod));
|
||||
return totalTime.plus(totalTimeFrequency.minus(intervalMod));
|
||||
}
|
||||
|
||||
private boolean isTimeFrequency() {
|
||||
return taskFrequency > 0;
|
||||
@VisibleForTesting
|
||||
@NonNull
|
||||
public Duration getNextTotalTime() {
|
||||
return nextTotalTime;
|
||||
}
|
||||
|
||||
private boolean isDistanceFrequency() {
|
||||
return taskFrequency < 0;
|
||||
@VisibleForTesting
|
||||
@NonNull
|
||||
public Distance getNextTotalDistance() {
|
||||
return nextTotalDistance;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user