diff --git a/app/res/values-de/cues.xml b/app/res/values-de/cues.xml index cb68fa3fb..2e8a6159d 100644 --- a/app/res/values-de/cues.xml +++ b/app/res/values-de/cues.xml @@ -14,20 +14,20 @@ ~ ~ You should have received a copy of the GNU General Public License ~ along with this program. If not, see .--> - Aktivität - Intervall - Runde + 0<Aktivität + 0<Intervall + 0<Runde Aufwärmphase Abkühlphase Aktuell Erholung pro Kilometer pro Meile - begonnen - pausiert - fortgeführt - gestoppt - abgeschlossen + 0<begonnen + 0<pausiert + 0<fortgeführt + 0<gestoppt + 0<abgeschlossen beschleunige werde langsamer diff --git a/app/res/values-en-rNL/cues.xml b/app/res/values-en-rNL/cues.xml index c541ebcb1..5fea66dc4 100644 --- a/app/res/values-en-rNL/cues.xml +++ b/app/res/values-en-rNL/cues.xml @@ -14,20 +14,20 @@ ~ ~ You should have received a copy of the GNU General Public License ~ along with this program. If not, see .--> - activiteit - interval - ronde + 0<activiteit + 0<interval + 0<ronde warming-up cooling-down huidige herstel per kilometer per mijl - gestart - gepauzeerd - hervatten - gestopt - afgerond + 0<gestart + 0<gepauzeerd + 0<hervatten + 0<gestopt + 0<afgerond versnellen vertragen diff --git a/app/res/values-es/cues.xml b/app/res/values-es/cues.xml index 76a5f939b..5dc65e32a 100644 --- a/app/res/values-es/cues.xml +++ b/app/res/values-es/cues.xml @@ -14,19 +14,19 @@ ~ ~ You should have received a copy of the GNU General Public License ~ along with this program. If not, see .--> - actividad - intervalo - vuelta + 0<actividad + 0<intervalo + 0<vuelta calentamiento enfriamiento actual por kilómetro por milla - empezado - en pausa - reanudado - parado - completado + 0<empezado + 0<en pausa + 0<reanudado + 0<parado + 0<completado acelerar decelerar diff --git a/app/res/values-fr/cues.xml b/app/res/values-fr/cues.xml index 41ef1e344..5831c276d 100644 --- a/app/res/values-fr/cues.xml +++ b/app/res/values-fr/cues.xml @@ -14,20 +14,20 @@ ~ ~ You should have received a copy of the GNU General Public License ~ along with this program. If not, see .--> - activité - intervalle - tour + 0<activité + 0<intervalle + 0<tour échauffement refroidissement courant récupération par kilomètre par mille - démarré - pausé - repris - stoppé - terminé + 0<démarré + 0<pausé + 0<repris + 0<stoppé + 0<terminé accéléré ralentir diff --git a/app/res/values-nl-rNL/cues.xml b/app/res/values-nl-rNL/cues.xml index c541ebcb1..5fea66dc4 100644 --- a/app/res/values-nl-rNL/cues.xml +++ b/app/res/values-nl-rNL/cues.xml @@ -14,20 +14,20 @@ ~ ~ You should have received a copy of the GNU General Public License ~ along with this program. If not, see .--> - activiteit - interval - ronde + 0<activiteit + 0<interval + 0<ronde warming-up cooling-down huidige herstel per kilometer per mijl - gestart - gepauzeerd - hervatten - gestopt - afgerond + 0<gestart + 0<gepauzeerd + 0<hervatten + 0<gestopt + 0<afgerond versnellen vertragen diff --git a/app/res/values-nl/cues.xml b/app/res/values-nl/cues.xml index c541ebcb1..5fea66dc4 100644 --- a/app/res/values-nl/cues.xml +++ b/app/res/values-nl/cues.xml @@ -14,20 +14,20 @@ ~ ~ You should have received a copy of the GNU General Public License ~ along with this program. If not, see .--> - activiteit - interval - ronde + 0<activiteit + 0<interval + 0<ronde warming-up cooling-down huidige herstel per kilometer per mijl - gestart - gepauzeerd - hervatten - gestopt - afgerond + 0<gestart + 0<gepauzeerd + 0<hervatten + 0<gestopt + 0<afgerond versnellen vertragen diff --git a/app/res/values-pl/cues.xml b/app/res/values-pl/cues.xml index 7a2ffe150..4a0da1035 100644 --- a/app/res/values-pl/cues.xml +++ b/app/res/values-pl/cues.xml @@ -14,20 +14,23 @@ ~ ~ You should have received a copy of the GNU General Public License ~ along with this program. If not, see .--> - aktywność - interwał - okrążenie + {1} {0} {2} + {0} {1} + 10#Treningu|20#Trening + 10#Interwału|20#interwał + 10#Okrążenia|20#Okrążenie + 1#{3}|2#{3}|3#{3}|4#{3}|5#{3}|6#{3} rozgrzewka uspokojenie aktualny regeneracja na kilometr na milę - rozpoczęte - zatrzymana - wznowiona - zatrzymana - zakończony + 101#rozpoczęty|102#rozpoczęty|103#rozpoczęte|112#rozpoczęta|115#rozpoczęte + 201#wstrzymany|202#wstrzymany|203#wstrzymane + 301#wznowiony|302#wznowiony|303#wznowione + 401#zatrzymany|402#zatrzymany|403#zatrzymane + 501#zakończony|502#zakończony|503#zakończone przyśpiesz zwolnij diff --git a/app/res/values-tr/cues.xml b/app/res/values-tr/cues.xml index b74484911..dd8f5e843 100644 --- a/app/res/values-tr/cues.xml +++ b/app/res/values-tr/cues.xml @@ -14,19 +14,19 @@ ~ ~ You should have received a copy of the GNU General Public License ~ along with this program. If not, see .--> - aktivite - aralık - tur + 0<aktivite + 0<aralık + 0<tur ısınma soğuma şimdiki kilometre başına mil başına - başlandı - duraklatıldı - devam edildi - durduruldu - tamamlandı + 0<başlandı + 0<duraklatıldı + 0<devam edildi + 0<durduruldu + 0<tamamlandı hızlan yavaşla diff --git a/app/res/values/cues.xml b/app/res/values/cues.xml index bae7cc9ae..e11be2233 100644 --- a/app/res/values/cues.xml +++ b/app/res/values/cues.xml @@ -14,20 +14,28 @@ ~ ~ You should have received a copy of the GNU General Public License ~ along with this program. If not, see .--> - activity - interval - lap + {0} {1} {2} + {0} {1} + 0<activity + 0<interval + 0<lap + + 1#|2#|3#|4#|5#|6#{3} warm up cool down current recovery per kilometer per mile - started - paused - resumed - stopped - completed + 0<started + 0<paused + 0<resumed + 0<stopped + 0<completed speed up slow down diff --git a/app/src/org/runnerup/util/Formatter.java b/app/src/org/runnerup/util/Formatter.java index 2cd6efb4b..f945e18f7 100644 --- a/app/src/org/runnerup/util/Formatter.java +++ b/app/src/org/runnerup/util/Formatter.java @@ -28,8 +28,12 @@ import android.text.format.DateUtils; import org.runnerup.R; +import org.runnerup.common.util.Constants; import org.runnerup.workout.Dimension; +import org.runnerup.workout.feedback.AudioFeedback; +import java.text.ChoiceFormat; +import java.text.MessageFormat; import java.util.Locale; @TargetApi(Build.VERSION_CODES.FROYO) @@ -57,6 +61,9 @@ public class Formatter implements OnSharedPreferenceChangeListener { public static final int TXT_SHORT = 5; // brief for printing public static final int TXT_LONG = 6; // long for printing + private static final int nounKeyBase = 10; + private static final int verbKeyBase = 100; + public Formatter(Context ctx) { context = ctx; resources = ctx.getResources(); @@ -274,12 +281,10 @@ private String formatHeartRateZone(int target, double hrZone) { case TXT_LONG: return Double.toString(Math.round(10.0 * hrZone) / 10.0); case CUE_SHORT: - return resources.getString(R.string.heartrate_zone) + " " - + Integer.toString((int) Math.floor(hrZone)); + return Integer.toString((int) Math.floor(hrZone)); case CUE: case CUE_LONG: - return resources.getString(R.string.heartrate_zone) + " " - + Double.toString(Math.floor(10.0 * hrZone) / 10.0); + return Double.toString(Math.floor(10.0 * hrZone) / 10.0); } return ""; } @@ -541,4 +546,66 @@ public static double getUnitMeters(Context mContext) { return getUnitMeters(mContext.getResources(), PreferenceManager.getDefaultSharedPreferences(mContext)); } + + + private static int getCueNounKey(AudioFeedback feedback) { + switch (feedback.getCueCase()) { + case Constants.CUE_CASE.EVENT: + case Constants.CUE_CASE.DIMENSION: + return nounKeyBase * feedback.getCueCase();//10,20,30 + case Constants.CUE_CASE.INTENSITY: + return -1; + default: + return 0; + } + } + + private static int getCueVerbKey(AudioFeedback feedback) { + switch (feedback.getCueCase()) { + case Constants.CUE_CASE.EVENT: + return verbKeyBase * feedback.getEvent().getValue() + feedback.getScope().getValue();//101,102,103,104 + case Constants.CUE_CASE.DIMENSION: + return -1; + case Constants.CUE_CASE.INTENSITY: + return verbKeyBase * feedback.getEvent().getValue() + (feedback.getIntensity().getValue()+2) * feedback.getCueCase();//106,109,112,115,118,121 + default: + return 0; + } + } + + public String formatCueSentence(MessageFormat sentence, double val, AudioFeedback feedback) { + + ChoiceFormat cueNounPattern, cueVerbPattern, cueDimensionPattern; + + switch (feedback.getCueCase()) { + case Constants.CUE_CASE.EVENT: + + cueNounPattern = new ChoiceFormat(resources.getString(feedback.getScope().getCueId())); + sentence.setFormatByArgumentIndex(0, cueNounPattern); + + cueVerbPattern = new ChoiceFormat(resources.getString(feedback.getEvent().getCueId())); + sentence.setFormatByArgumentIndex(1, cueVerbPattern); + + return sentence.format(new Object[] {getCueNounKey(feedback), getCueVerbKey(feedback)}); + + case Constants.CUE_CASE.DIMENSION: + + cueDimensionPattern = new ChoiceFormat(resources.getString(R.string.cue_dimension_pattern)); + sentence.setFormatByArgumentIndex(1, cueDimensionPattern); + + cueNounPattern = new ChoiceFormat(resources.getString(feedback.getScope().getCueId())); + sentence.setFormatByArgumentIndex(0, cueNounPattern); + + return sentence.format(new Object[] {getCueNounKey(feedback), feedback.getDimension().getValue(), format(Formatter.CUE_LONG, feedback.getDimension(), val), resources.getString(feedback.getDimension().getTextId())}); + + case Constants.CUE_CASE.INTENSITY: + + cueVerbPattern = new ChoiceFormat(resources.getString(feedback.getEvent().getCueId())); + sentence.setFormatByArgumentIndex(1, cueVerbPattern); + + return sentence.format(new Object[] {resources.getString(feedback.getIntensity().getCueId()), getCueVerbKey(feedback)}); + default: + return ""; + } + } } diff --git a/app/src/org/runnerup/workout/feedback/AudioFeedback.java b/app/src/org/runnerup/workout/feedback/AudioFeedback.java index b7df8daff..bb8960391 100644 --- a/app/src/org/runnerup/workout/feedback/AudioFeedback.java +++ b/app/src/org/runnerup/workout/feedback/AudioFeedback.java @@ -23,6 +23,8 @@ import android.os.Build; import android.speech.tts.TextToSpeech; +import org.runnerup.R; +import org.runnerup.common.util.Constants; import org.runnerup.util.Formatter; import org.runnerup.workout.Dimension; import org.runnerup.workout.Event; @@ -31,23 +33,28 @@ import org.runnerup.workout.Scope; import org.runnerup.workout.Workout; +import java.text.MessageFormat; import java.util.HashMap; @TargetApi(Build.VERSION_CODES.FROYO) public class AudioFeedback extends Feedback { + + Event event = Event.STARTED; Scope scope = Scope.WORKOUT; Dimension dimension = Dimension.DISTANCE; Intensity intensity = null; RUTextToSpeech textToSpeech; Formatter formatter; + int cueCase = 0; public AudioFeedback(Scope scope, Event event) { super(); this.scope = scope; this.event = event; this.dimension = null; + this.cueCase = Constants.CUE_CASE.EVENT; } public AudioFeedback(Scope scope, Dimension dimension) { @@ -55,6 +62,7 @@ public AudioFeedback(Scope scope, Dimension dimension) { this.scope = scope; this.event = null; this.dimension = dimension; + this.cueCase = Constants.CUE_CASE.DIMENSION; } public AudioFeedback(Intensity intensity, Event event) { @@ -63,6 +71,7 @@ public AudioFeedback(Intensity intensity, Event event) { this.dimension = null; this.intensity = intensity; this.event = event; + this.cueCase = Constants.CUE_CASE.INTENSITY; } @Override @@ -92,24 +101,50 @@ public boolean equals(Feedback _other) { return true; } - protected String getCue(Workout w, Context ctx) { - String msg = null; + public Event getEvent() { + return event; + } + + public Scope getScope() { + return scope; + } + + public Dimension getDimension() { + return dimension; + } + + public Intensity getIntensity() { + return intensity; + } + + public int getCueCase() { + return cueCase; + } + + + protected String getCue(Workout w, Context ctx, double val) { + String msg = ""; Resources res = ctx.getResources(); if (event != null && scope != null) { - msg = res.getString(scope.getCueId()) + " " + res.getString(event.getCueId()); + MessageFormat sentence = new MessageFormat(res.getString(R.string.cue_event_pattern)); + msg = formatter.formatCueSentence(sentence, val, this); } else if (event != null && intensity != null) { - msg = res.getString(intensity.getCueId(), "") + " " + res.getString(event.getCueId()); + MessageFormat sentence = new MessageFormat(res.getString(R.string.cue_event_pattern)); + msg = formatter.formatCueSentence(sentence, val, this); } else if (dimension != null && scope != null && w.isEnabled(dimension, scope)) { - double val = w.get(scope, dimension); // SI - msg = res.getString(scope.getCueId()) + " " - + formatter.format(Formatter.CUE_LONG, dimension, val); + MessageFormat sentence = new MessageFormat(res.getString(R.string.cue_interval_pattern)); + msg = formatter.formatCueSentence(sentence, val, this); } return msg; } @Override public void emit(Workout w, Context ctx) { - String msg = getCue(w, ctx); + double val = 0; + if(scope != null && dimension != null) { + val = w.get(scope, dimension); + } + String msg = getCue(w, ctx, val); if (msg != null) { textToSpeech.speak(msg, TextToSpeech.QUEUE_ADD, null); } diff --git a/app/src/org/runnerup/workout/feedback/CoachFeedback.java b/app/src/org/runnerup/workout/feedback/CoachFeedback.java index 8eefe0403..1007c5040 100644 --- a/app/src/org/runnerup/workout/feedback/CoachFeedback.java +++ b/app/src/org/runnerup/workout/feedback/CoachFeedback.java @@ -96,9 +96,7 @@ public void emit(Workout s, Context ctx) { msg = " " + ctx.getResources().getString(R.string.cue_slowdown); } if (!"".contentEquals(msg)) { - textToSpeech.speak(ctx.getResources().getString(scope.getCueId()) - + " " - + formatter.format(Formatter.CUE_LONG, dimension, val) + textToSpeech.speak(getCue(s, ctx, val) + msg, TextToSpeech.QUEUE_ADD, null); } diff --git a/common/src/main/java/org/runnerup/common/util/Constants.java b/common/src/main/java/org/runnerup/common/util/Constants.java index 4fbe71ea4..cd9ff03a2 100644 --- a/common/src/main/java/org/runnerup/common/util/Constants.java +++ b/common/src/main/java/org/runnerup/common/util/Constants.java @@ -180,6 +180,12 @@ public interface TRACKER_STATE { public static final int STOPPED = 9; }; + public interface CUE_CASE { + public static final int DIMENSION = 1; + public static final int EVENT = 2; + public static final int INTENSITY = 3; + } + public interface Wear { public interface Path {