From bc0713bc0dac86b781c485ddbe3a4e05c3f21c4b Mon Sep 17 00:00:00 2001 From: mikunimaru <43168745+mikunimaru@users.noreply.github.com> Date: Thu, 13 May 2021 00:13:37 +0900 Subject: [PATCH 01/15] New JavaScript api for TTS Since it is unlikely that a beginner will handle this api, I moved the functions on the android side to JavaScript with as little modification as possible. Since the function conversion rules have been simplified, the api can be extended with consistent rules even if other TTS functions are needed on the JavaScript side in the future. --- .../ichi2/anki/AbstractFlashcardViewer.java | 44 ++++++++ .../java/com/ichi2/anki/JavaScriptTTS.java | 103 ++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.java b/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.java index b666b8d742e7..b4aa8409b7c8 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.java +++ b/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.java @@ -4212,5 +4212,49 @@ public boolean ankiIsActiveNetworkMetered() { return true; } } + + //Voice reading + JavaScriptTTS mTalker = new JavaScriptTTS (AbstractFlashcardViewer.this); + + @JavascriptInterface + public int ankiTtsSpeak(String text, int queueMode) { + return mTalker.speak(text, queueMode); + } + + @JavascriptInterface + public int ankiTtsSpeak(String text) { + return mTalker.speak(text); + } + + @JavascriptInterface + public int ankiTtsSetLanguage(String loc) { + return mTalker.setLanguage(loc); + } + + @JavascriptInterface + public int ankiTtsSetPitch(float pitch) { + return mTalker.setPitch(pitch); + } + + @JavascriptInterface + public int ankiTtsSetPitch(double pitch) { + return mTalker.setPitch((float)pitch); + } + + @JavascriptInterface + public int ankiTtsSetSpeechRate(float speechRate) { + return mTalker.setSpeechRate(speechRate); + } + + @JavascriptInterface + public int ankiTtsSetSpeechRate(double speechRate) { + return mTalker.setSpeechRate((float)speechRate); + } + + @JavascriptInterface + public void ankiTtsStop() { + mTalker.stop(); + } + } } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java b/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java new file mode 100644 index 000000000000..ffa377e741bb --- /dev/null +++ b/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java @@ -0,0 +1,103 @@ +package com.ichi2.anki; + +import android.content.Context; +import android.os.Bundle; +import android.speech.tts.TextToSpeech; +import java.util.Locale; + +// Since it is assumed that only advanced users will use the JavaScript api, +// here, Android's TextToSpeech is converted for JavaScript almost as it is, giving priority to free behavior. +// https://developer.android.com/reference/android/speech/tts/TextToSpeech +// +// + +public class JavaScriptTTS implements TextToSpeech.OnInitListener { + + private TextToSpeech mTts; + private boolean mTtsOk; + private static final Bundle mTtsParams = new Bundle(); + + //The constructor will create a TextToSpeech instance. + JavaScriptTTS(Context context) { + mTts = new TextToSpeech(context, this); + } + + @Override + //OnInitListener method to receive the TTS engine status + public void onInit(int status) { + if (status == TextToSpeech.SUCCESS) { + mTtsOk = true; + } + else { + mTtsOk = false; + } + } + + // A method to speak something + // The QueMode value is 1 for QUEUE_ADD and 0 for QUEUE_FLUSH. + public int speak(String text, int queueMode) { + return mTts.speak(text, queueMode, mTtsParams, "stringId"); + } + + // If only a string is given, set QUEUE_FLUSH to the default behavior. + public int speak(String text) { + return mTts.speak(text, TextToSpeech.QUEUE_FLUSH, mTtsParams, "stringId"); + } + + // Sets the text-to-speech language. + //The TTS engine will try to use the closest match to the specified language as represented by the Locale, but there is no guarantee that the exact same Locale will be used. + public int setLanguage(String loc) { + // The Int values will be returned + // Code indicating the support status for the locale. See LANG_AVAILABLE, LANG_COUNTRY_AVAILABLE, LANG_COUNTRY_VAR_AVAILABLE, LANG_MISSING_DATA and LANG_NOT_SUPPORTED. + return mTts.setLanguage(localeFromStringIgnoringScriptAndExtensions(loc)); + } + + // Sets the speech pitch for the TextToSpeech engine. This has no effect on any pre-recorded speech. + // float: Speech pitch. 1.0 is the normal pitch, lower values lower the tone of the synthesized voice, greater values increase it. + public int setPitch(float pitch) { + // The following Int values will be returned + // ERROR(-1) SUCCESS(0) + return mTts.setPitch(pitch); + } + + // Sets the speech rate. This has no effect on any pre-recorded speech. + public int setSpeechRate(float speechRate) { + // The following Int values will be returned + // ERROR(-1) SUCCESS(0) + return mTts.setSpeechRate(speechRate); + } + + // Interrupts the current utterance (whether played or rendered to file) and discards other utterances in the queue. + public void stop() { + // The following Int values will be returned + // ERROR(-1) SUCCESS(0) + mTts.stop(); + } + + /** + * Convert a string representation of a locale, in the format returned by Locale.toString(), + * into a Locale object, disregarding any script and extensions fields (i.e. using solely the + * language, country and variant fields). + *
+ * Returns a Locale object constructed from an empty string if the input string is null, empty + * or contains more than 3 fields separated by underscores. + */ + private static Locale localeFromStringIgnoringScriptAndExtensions(String localeCode) { + if (localeCode == null) { + return new Locale(""); + } + + String[] fields = localeCode.split("_"); + switch (fields.length) { + case 1: + return new Locale(fields[0]); + case 2: + return new Locale(fields[0], fields[1]); + case 3: + return new Locale(fields[0], fields[1], fields[2]); + default: + return new Locale(""); + } + } + +} \ No newline at end of file From d9023e2de100f9501d349968b6e7fdb2a6830d48 Mon Sep 17 00:00:00 2001 From: mikunimaru <43168745+mikunimaru@users.noreply.github.com> Date: Wed, 2 Jun 2021 15:42:02 +0900 Subject: [PATCH 02/15] Code style and comment fixes --- .../ichi2/anki/AbstractFlashcardViewer.java | 12 ++-- .../java/com/ichi2/anki/JavaScriptTTS.java | 60 +++++++++++++------ 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.java b/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.java index b4aa8409b7c8..421f7fa64a43 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.java +++ b/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.java @@ -4214,31 +4214,31 @@ public boolean ankiIsActiveNetworkMetered() { } //Voice reading - JavaScriptTTS mTalker = new JavaScriptTTS (AbstractFlashcardViewer.this); + JavaScriptTTS mTalker = new JavaScriptTTS(AbstractFlashcardViewer.this); @JavascriptInterface public int ankiTtsSpeak(String text, int queueMode) { - return mTalker.speak(text, queueMode); + return mTalker.speak(text, queueMode); } @JavascriptInterface public int ankiTtsSpeak(String text) { - return mTalker.speak(text); + return mTalker.speak(text); } @JavascriptInterface public int ankiTtsSetLanguage(String loc) { - return mTalker.setLanguage(loc); + return mTalker.setLanguage(loc); } @JavascriptInterface public int ankiTtsSetPitch(float pitch) { - return mTalker.setPitch(pitch); + return mTalker.setPitch(pitch); } @JavascriptInterface public int ankiTtsSetPitch(double pitch) { - return mTalker.setPitch((float)pitch); + return mTalker.setPitch((float)pitch); } @JavascriptInterface diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java b/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java index ffa377e741bb..b5ed36a3826e 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java +++ b/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java @@ -5,25 +5,23 @@ import android.speech.tts.TextToSpeech; import java.util.Locale; -// Since it is assumed that only advanced users will use the JavaScript api, -// here, Android's TextToSpeech is converted for JavaScript almost as it is, giving priority to free behavior. -// https://developer.android.com/reference/android/speech/tts/TextToSpeech -// -// - +/** + * Since it is assumed that only advanced users will use the JavaScript api, + * here, Android's TextToSpeech is converted for JavaScript almost as it is, giving priority to free behavior. + * https://developer.android.com/reference/android/speech/tts/TextToSpeech + */ public class JavaScriptTTS implements TextToSpeech.OnInitListener { private TextToSpeech mTts; private boolean mTtsOk; private static final Bundle mTtsParams = new Bundle(); - //The constructor will create a TextToSpeech instance. JavaScriptTTS(Context context) { mTts = new TextToSpeech(context, this); } @Override - //OnInitListener method to receive the TTS engine status + /** OnInitListener method to receive the TTS engine status */ public void onInit(int status) { if (status == TextToSpeech.SUCCESS) { mTtsOk = true; @@ -32,42 +30,68 @@ public void onInit(int status) { mTtsOk = false; } } - - // A method to speak something - // The QueMode value is 1 for QUEUE_ADD and 0 for QUEUE_FLUSH. + + /** + * A method to speak something + * @param text Content to speak + * @param queueMode 1 for QUEUE_ADD and 0 for QUEUE_FLUSH. + * @return ERROR(-1) SUCCESS(0) + */ public int speak(String text, int queueMode) { return mTts.speak(text, queueMode, mTtsParams, "stringId"); } - // If only a string is given, set QUEUE_FLUSH to the default behavior. + /** + * If only a string is given, set QUEUE_FLUSH to the default behavior. + * @param text Content to speak + * @return ERROR(-1) SUCCESS(0) + */ public int speak(String text) { return mTts.speak(text, TextToSpeech.QUEUE_FLUSH, mTtsParams, "stringId"); } - // Sets the text-to-speech language. - //The TTS engine will try to use the closest match to the specified language as represented by the Locale, but there is no guarantee that the exact same Locale will be used. + /** + * Sets the text-to-speech language. + * The TTS engine will try to use the closest match to the specified language as represented by the Locale, but there is no guarantee that the exact same Locale will be used. + * @param loc Specifying the language to speak + * @return 0 Denotes the language is available for the language by the locale, but not the country and variant. + *
- * Returns a Locale object constructed from an empty string if the input string is null, empty - * or contains more than 3 fields separated by underscores. - */ - private static Locale localeFromStringIgnoringScriptAndExtensions(String localeCode) { - if (localeCode == null) { - return new Locale(""); - } - - String[] fields = localeCode.split("_"); - switch (fields.length) { - case 1: - return new Locale(fields[0]); - case 2: - return new Locale(fields[0], fields[1]); - case 3: - return new Locale(fields[0], fields[1], fields[2]); - default: - return new Locale(""); - } - } - } \ No newline at end of file diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/LanguageUtils.java b/AnkiDroid/src/main/java/com/ichi2/anki/LanguageUtils.java new file mode 100644 index 000000000000..b549211ff436 --- /dev/null +++ b/AnkiDroid/src/main/java/com/ichi2/anki/LanguageUtils.java @@ -0,0 +1,42 @@ +package com.ichi2.anki; + +import java.util.Locale; + +public class LanguageUtils { + + /** + * Convert a string representation of a locale, in the format returned by Locale.toString(), + * into a Locale object, disregarding any script and extensions fields (i.e. using solely the + * language, country and variant fields). + *
+ * Returns a Locale object constructed from an empty string if the input string is null, empty + * or contains more than 3 fields separated by underscores. + */ + public static Locale localeFromStringIgnoringScriptAndExtensions(String localeCode) { + if (localeCode == null) { + return new Locale(""); + } + + localeCode = stripScriptAndExtensions(localeCode); + + String[] fields = localeCode.split("_"); + switch (fields.length) { + case 1: + return new Locale(fields[0]); + case 2: + return new Locale(fields[0], fields[1]); + case 3: + return new Locale(fields[0], fields[1], fields[2]); + default: + return new Locale(""); + } + } + + private static String stripScriptAndExtensions(String localeCode) { + int hashPos = localeCode.indexOf('#'); + if (hashPos >= 0) { + localeCode = localeCode.substring(0, hashPos); + } + return localeCode; + } +} \ No newline at end of file diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/ReadText.java b/AnkiDroid/src/main/java/com/ichi2/anki/ReadText.java index fdc4db57a2f8..1ff15f5462ab 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/ReadText.java +++ b/AnkiDroid/src/main/java/com/ichi2/anki/ReadText.java @@ -29,6 +29,7 @@ import com.afollestad.materialdialogs.MaterialDialog; import com.google.android.material.snackbar.Snackbar; import com.ichi2.libanki.Sound; +import com.ichi2.anki.LanguageUtils; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -56,7 +57,7 @@ public static Sound.SoundSide getmQuestionAnswer() { } public static void speak(String text, String loc, int queueMode) { - int result = mTts.setLanguage(localeFromStringIgnoringScriptAndExtensions(loc)); + int result = mTts.setLanguage(LanguageUtils.localeFromStringIgnoringScriptAndExtensions(loc)); if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { UIUtils.showThemedToast(mReviewer.get(), mReviewer.get().getString(R.string.no_tts_available_message) + " (" + loc + ")", false); @@ -218,48 +219,12 @@ private static void textToSpeech(String text, long did, int ord, Sound.SoundSide selectTts(mTextToSpeak, mDid, mOrd, mQuestionAnswer); } - /** - * Convert a string representation of a locale, in the format returned by Locale.toString(), - * into a Locale object, disregarding any script and extensions fields (i.e. using solely the - * language, country and variant fields). - *
- * Returns a Locale object constructed from an empty string if the input string is null, empty - * or contains more than 3 fields separated by underscores. - */ - private static Locale localeFromStringIgnoringScriptAndExtensions(String localeCode) { - if (localeCode == null) { - return new Locale(""); - } - - localeCode = stripScriptAndExtensions(localeCode); - - String[] fields = localeCode.split("_"); - switch (fields.length) { - case 1: - return new Locale(fields[0]); - case 2: - return new Locale(fields[0], fields[1]); - case 3: - return new Locale(fields[0], fields[1], fields[2]); - default: - return new Locale(""); - } - } - - private static String stripScriptAndExtensions(String localeCode) { - int hashPos = localeCode.indexOf('#'); - if (hashPos >= 0) { - localeCode = localeCode.substring(0, hashPos); - } - return localeCode; - } - /** * Returns true if the TTS engine supports the language of the locale represented by localeCode * (which should be in the format returned by Locale.toString()), false otherwise. */ private static boolean isLanguageAvailable(String localeCode) { - return mTts.isLanguageAvailable(localeFromStringIgnoringScriptAndExtensions(localeCode)) >= + return mTts.isLanguageAvailable(LanguageUtils.localeFromStringIgnoringScriptAndExtensions(localeCode)) >= TextToSpeech.LANG_AVAILABLE; } From 7ae67152548a9b51d1fb7141724e34257f290b00 Mon Sep 17 00:00:00 2001 From: mikunimaru <43168745+mikunimaru@users.noreply.github.com> Date: Wed, 2 Jun 2021 16:54:49 +0900 Subject: [PATCH 04/15] Fixed verbose code in JavaScript TTS class --- AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java b/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java index dc7ef6bbebf4..1f3e63689553 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java +++ b/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java @@ -24,12 +24,7 @@ public class JavaScriptTTS implements TextToSpeech.OnInitListener { @Override /** OnInitListener method to receive the TTS engine status */ public void onInit(int status) { - if (status == TextToSpeech.SUCCESS) { - mTtsOk = true; - } - else { - mTtsOk = false; - } + mTtsOk = status == TextToSpeech.SUCCESS; } /** From 33feffac15b23a42345bd5b5ad9cc81dc5b3df68 Mon Sep 17 00:00:00 2001 From: mikunimaru <43168745+mikunimaru@users.noreply.github.com> Date: Wed, 2 Jun 2021 17:03:11 +0900 Subject: [PATCH 05/15] Code style fixes --- AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java b/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java index 1f3e63689553..4857b166ddc5 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java +++ b/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java @@ -21,12 +21,12 @@ public class JavaScriptTTS implements TextToSpeech.OnInitListener { mTts = new TextToSpeech(context, this); } - @Override /** OnInitListener method to receive the TTS engine status */ + @Override public void onInit(int status) { mTtsOk = status == TextToSpeech.SUCCESS; } - + /** * A method to speak something * @param text Content to speak From feafb9bbea66a8b2f53b75b7e1dd12d4199c1bcb Mon Sep 17 00:00:00 2001 From: mikunimaru <43168745+mikunimaru@users.noreply.github.com> Date: Wed, 2 Jun 2021 19:39:32 +0900 Subject: [PATCH 06/15] Move JavaScript TTS to the top of the class --- .../main/java/com/ichi2/anki/AbstractFlashcardViewer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.java b/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.java index 421f7fa64a43..6948ee0d5f06 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.java +++ b/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.java @@ -392,6 +392,9 @@ public abstract class AbstractFlashcardViewer extends NavigationDrawerActivity i /** Preference: Whether the user wants to focus "type in answer" */ private boolean mFocusTypeAnswer; + /** Text to speech */ + private JavaScriptTTS mTalker = new JavaScriptTTS(AbstractFlashcardViewer.this); + // ---------------------------------------------------------------------------- // LISTENERS // ---------------------------------------------------------------------------- @@ -4213,9 +4216,6 @@ public boolean ankiIsActiveNetworkMetered() { } } - //Voice reading - JavaScriptTTS mTalker = new JavaScriptTTS(AbstractFlashcardViewer.this); - @JavascriptInterface public int ankiTtsSpeak(String text, int queueMode) { return mTalker.speak(text, queueMode); From 14107a27602f479a986dff39b334bb91e3b66b0c Mon Sep 17 00:00:00 2001 From: mikunimaru <43168745+mikunimaru@users.noreply.github.com> Date: Thu, 3 Jun 2021 07:40:04 +0900 Subject: [PATCH 07/15] Added NonNull annotation --- AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java b/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java index 4857b166ddc5..cc9ad42768c1 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java +++ b/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java @@ -6,6 +6,8 @@ import com.ichi2.anki.LanguageUtils; +import androidx.annotation.NonNull; + /** * Since it is assumed that only advanced users will use the JavaScript api, * here, Android's TextToSpeech is converted for JavaScript almost as it is, giving priority to free behavior. @@ -13,8 +15,9 @@ */ public class JavaScriptTTS implements TextToSpeech.OnInitListener { - private TextToSpeech mTts; - private boolean mTtsOk; + @NonNull + private static TextToSpeech mTts; + private static boolean mTtsOk; private static final Bundle mTtsParams = new Bundle(); JavaScriptTTS(Context context) { From 8a095684277f93ec9a52bc1fb042d0d92aa2b0bb Mon Sep 17 00:00:00 2001 From: mikunimaru <43168745+mikunimaru@users.noreply.github.com> Date: Thu, 3 Jun 2021 10:55:37 +0900 Subject: [PATCH 08/15] Force int value through IntDef --- .../java/com/ichi2/anki/JavaScriptTTS.java | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java b/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java index cc9ad42768c1..99e07f336821 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java +++ b/AnkiDroid/src/main/java/com/ichi2/anki/JavaScriptTTS.java @@ -6,6 +6,7 @@ import com.ichi2.anki.LanguageUtils; +import androidx.annotation.IntDef; import androidx.annotation.NonNull; /** @@ -15,6 +16,25 @@ */ public class JavaScriptTTS implements TextToSpeech.OnInitListener { + private static final int TTS_SUCCESS = TextToSpeech.SUCCESS; + private static final int TTS_ERROR = TextToSpeech.ERROR; + private static final int TTS_QUEUE_ADD = TextToSpeech.QUEUE_ADD; + private static final int TTS_QUEUE_FLUSH = TextToSpeech.QUEUE_FLUSH; + private static final int TTS_LANG_AVAILABLE = TextToSpeech.LANG_AVAILABLE; + private static final int TTS_LANG_COUNTRY_AVAILABLE = TextToSpeech.LANG_COUNTRY_AVAILABLE; + private static final int TTS_LANG_COUNTRY_VAR_AVAILABLE = TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE; + private static final int TTS_LANG_MISSING_DATA = TextToSpeech.LANG_MISSING_DATA; + private static final int TTS_LANG_NOT_SUPPORTED = TextToSpeech.LANG_NOT_SUPPORTED; + + @IntDef({TTS_SUCCESS, TTS_ERROR}) + public @interface ErrorOrSuccess {} + + @IntDef({TTS_QUEUE_ADD, TTS_QUEUE_FLUSH}) + public @interface QueueMode {} + + @IntDef({TTS_LANG_AVAILABLE, TTS_LANG_COUNTRY_AVAILABLE, TTS_LANG_COUNTRY_VAR_AVAILABLE, TTS_LANG_MISSING_DATA, TTS_LANG_NOT_SUPPORTED}) + public @interface TTSLangResult {} + @NonNull private static TextToSpeech mTts; private static boolean mTtsOk; @@ -26,7 +46,7 @@ public class JavaScriptTTS implements TextToSpeech.OnInitListener { /** OnInitListener method to receive the TTS engine status */ @Override - public void onInit(int status) { + public void onInit(@ErrorOrSuccess int status) { mTtsOk = status == TextToSpeech.SUCCESS; } @@ -36,7 +56,8 @@ public void onInit(int status) { * @param queueMode 1 for QUEUE_ADD and 0 for QUEUE_FLUSH. * @return ERROR(-1) SUCCESS(0) */ - public int speak(String text, int queueMode) { + @ErrorOrSuccess + public int speak(String text, @QueueMode int queueMode) { return mTts.speak(text, queueMode, mTtsParams, "stringId"); } @@ -45,6 +66,7 @@ public int speak(String text, int queueMode) { * @param text Content to speak * @return ERROR(-1) SUCCESS(0) */ + @ErrorOrSuccess public int speak(String text) { return mTts.speak(text, TextToSpeech.QUEUE_FLUSH, mTtsParams, "stringId"); } @@ -59,6 +81,7 @@ public int speak(String text) { *