When my app is first installed or opened after being destroyed, it works great. If you back out of it and go back in, then the onStart in UtteranceProgressListener never fires after onInit in OnInitListner. When I open the app after backing out, everything else seems to be working. Log shows that onInit is called, but it never progresses to the onStart in the UtteranceProgressListener. How can I make this work?
in my onCreate:
// Implement Text to speech feature
tts = getTts();
// set progress listener to the TTS engine
tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onStart(String utteranceId) {
Log.d("LOOK AT ME!!!", "ttsUtteranceListener - onStart");
}
#Override
public void onError(String utteranceId) {
Log.d("LOOK AT ME!!!", "ttsUtteranceListener - onError");
}
#Override
public void onDone(String utteranceId) {
Log.d("LOOK AT ME!!!", "ttsUtteranceListener - onDone");
if (processStarted) {
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Log.d("LOOK AT ME!!!",
"ttsUtteranceListener - speech,startListening");
speech.startListening(intent);
}
});
} else {
...
}
processStarted = false;
}
});
and here is "getTts()":
private TextToSpeech getTts() {
if (tts == null) {
// Implement Text to speech feature
tts = new TextToSpeech(this, new OnInitListener() {
#Override
public void onInit(int status) {
Log.d("LOOK AT ME!!!", "ttsInitListener - onInit");
if (status == TextToSpeech.SUCCESS) {
tts.setLanguage(Locale.getDefault());
} else {
tts = null;
Toast.makeText(MainActivity.this,
"Failed to initialize TTS engine.",
Toast.LENGTH_SHORT).show();
}
}
});
}
return tts;
}
and here are my lifecycle calls (onPause and onResume) :
// --- LIFECYCLE ---
#Override
public void onResume() {
super.onResume();
Log.d("LOOK AT ME!!!", "onResume");
if (tts == null) {
tts = getTts();
}
}
#Override
public void onPause() {
// Stop then shut down the TextToSpeech Engine
if (tts != null) {
tts.stop();
tts.shutdown();
tts = null;
}
super.onPause();
}
Related
I'm using Android Studio. Code java.I want to make TextToSpeech language Turkish.How can I make the voice Turkish?
my code:
TextToSpeech textToSpeech ;
ImageView ımagespeech;
textToSpeech = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
#Override
public void onInit(int i) {
if (i !=TextToSpeech.ERROR){
textToSpeech.setLanguage(new Locale("en_US"));
textToSpeech.setSpeechRate((float)1.0);
}
}
});
ımagespeech.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String gettext =tvtcontextt.getText().toString();
textToSpeech.speak(gettext,TextToSpeech.QUEUE_FLUSH,null);
}
});
#Override
protected void onPause() {
if (textToSpeech != null ){
textToSpeech.stop();
textToSpeech.shutdown();
}
super.onPause();
}
I recently discovered this languages. The speech quality looks promising on the web app.
Give it a shot :)
this is my solution,
in this way the code selects the language used in the device:
private TextToSpeech tts;
#Override
public void onResume() {
super.onResume();
//((AppCompatActivity) getActivity()).getSupportActionBar().hide();
tts = new TextToSpeech(requireContext(), new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
//int result = tts.setLanguage(Locale.forLanguageTag("en-US"));
int result = tts.setLanguage(Locale.forLanguageTag(Locale.getDefault().toLanguageTag()));
if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("TTS", "The Language not supported!");
} else {
Log.d("TTS", "TTS its working");
}
}
}
});
}
// in your code
tts.speak("read this", TextToSpeech.QUEUE_FLUSH, null, "");
#Override
public void onPause() {
if (tts != null) {
tts.stop();
tts.shutdown();
}
super.onPause();
}
I am getting error "android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views" when I call listenButton.setAlpha((float)1) in the code below. I understand why, but how can I then modify a button when I receive the onDone event?
public class MainActivity extends ActionBarActivity implements TextToSpeech.OnInitListener {
[...]
#Override
// OnInitListener method to receive the TTS engine status
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
ttsOK = true;
tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onDone(String utteranceId) {
Button listenButton = (Button) findViewById(R.id.listentts);
listenButton.setAlpha((float)1);
listenButton.setClickable(true);
}
#Override
public void onError(String utteranceId) {
Log.d("MainActivity", "Progress on Error " + utteranceId);
}
#Override
public void onStart(String utteranceId) {
Log.d("MainActivity", "Progress on Start " + utteranceId);
}
});
}
else {
ttsOK = false;
}
}
[...]
}
Every View has a Handler associated with it, so there's no need to create a new one.
final View v = findViewById(R.id.listentts); // could be a class member
v.getHandler().post(new Runnable() {
#Override
public void run() {
v.setAlpha(1.0f);
v.setClickable(true);
}
});
Try this:
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Button listenButton = (Button) findViewById(R.id.listentts);
listenButton.setAlpha((float)1);
listenButton.setClickable(true);
}
});
I'm trying to get the activity to finish after it's finished speaking but for some reason I cannot fathom it tells me that the setOnUtteranceCompleted not applicable for text to speech. I'm new to android programming so please be gentle :-)
Here's the code...
public class SpeakActivity extends Activity implements OnUtteranceCompletedListener{
Random randnum = new Random();
TextToSpeech tts = null;
private boolean ttsIsInit = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_speak);
// Show the Up button in the action bar.
setupActionBar();
startTextToSpeech();
}
void startTextToSpeech(){
final int randint = randnum.nextInt(4);
final String text = ((GlobVars) this.getApplication()).getResponse(randint);
tts = new TextToSpeech(this, new OnInitListener() {
public void onInit(int status) {
tts.setOnUtteranceCompletedListener(this);
if (status == TextToSpeech.SUCCESS) {
ttsIsInit = true;
if (tts.isLanguageAvailable(Locale.ENGLISH) >= 0){
tts.setLanguage(Locale.ENGLISH);
}
tts.setPitch(0.5f);
tts.setSpeechRate(0.5f);
if (tts != null && ttsIsInit) {
Log.d("got ere", "spoken");
tts.speak(text, TextToSpeech.QUEUE_ADD, null);
}
}
}
});
}
// shut down tts to free the TTS resources
#Override
public void onDestroy() {
if (tts != null) {
tts.stop();
tts.shutdown();
}
super.onDestroy();
}
#Override
public void onUtteranceCompleted(String arg0) {
((GlobVars) this.getApplication()).setListen(true);
this.finish();
}
}
I am ot sure but as per the docs of setOnUtteranceCompletedListener(), you might need to use TextToSpeech.OnUtteranceCompletedListener listener as an argument. I think the way to use the function is as below. Note that use runOnUIThread method in case you want to make any changes to the UI on the call of the onUtteranceCompleted function.
TextToSpeech tts= new TextToSpeech(context, new OnInitListener() {
#Override
public void onInit(int status) {
tts.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {
#Override
public void onUtteranceCompleted(String utteranceId) {
//Do things here
}
});
}
});
Source of above : Check onUtteranceCompleted does not get called? question.
Hope this helps.
I'm implementing an Interactive Voice Response application on Android. I would like to know how to determine when the tts.speak() function has done talking so I can call my speech recognizer function.
public class TTSActivity extends Activity implements OnInitListener, OnUtteranceCompletedListener, ... {
private TextToSpeech mTts;
...........
private void speak(String text) {
if(text != null) {
HashMap<String, String> myHashAlarm = new HashMap<String, String>();
myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_ALARM));
myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "SOME MESSAGE");
mTts.speak(text, TextToSpeech.QUEUE_FLUSH, myHashAlarm);
}
}
// Fired after TTS initialization
public void onInit(int status) {
if(status == TextToSpeech.SUCCESS) {
mTts.setOnUtteranceCompletedListener(this);
}
}
// It's callback
public void onUtteranceCompleted(String utteranceId) {
Log.i(TAG, utteranceId); //utteranceId == "SOME MESSAGE"
}
...........
}
Read A good tutorial
The setOnUtteranceCompletedListener is deprecated since API level 15. Instead, use setOnUtteranceProgressListener.
I found a code snippet (here) that made it really easy for me to know when text to speech is finished:
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
myTTS.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onDone(String utteranceId) {
// Log.d("MainActivity", "TTS finished");
}
#Override
public void onError(String utteranceId) {
}
#Override
public void onStart(String utteranceId) {
}
});
} else {
Log.e("MainActivity", "Initilization Failed!");
}
}
http://www.codota.com/android/scenarios/52fcbd34da0ae25e0f855408/android.speech.tts.TextToSpeech?tag=dragonfly
To know when TTS is finished you have to call the setOnUtteranceProgressListener which has 3 call back methods onStart,onDone and onError
then include a Utterance Id to the speak method
Code Snippet
textToSpeech=new TextToSpeech(this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status==TextToSpeech.SUCCESS){
int result=textToSpeech.setLanguage(Locale.ENGLISH);
if (result==TextToSpeech.LANG_MISSING_DATA||result==TextToSpeech.LANG_NOT_SUPPORTED){
Log.i("TextToSpeech","Language Not Supported");
}
textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onStart(String utteranceId) {
Log.i("TextToSpeech","On Start");
}
#Override
public void onDone(String utteranceId) {
Log.i("TextToSpeech","On Done");
}
#Override
public void onError(String utteranceId) {
Log.i("TextToSpeech","On Error");
}
});
}else {
Log.i("TextToSpeech","Initialization Failed");
}
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
textToSpeech.speak(text,TextToSpeech.QUEUE_FLUSH,null,TextToSpeech.ACTION_TTS_QUEUE_PROCESSING_COMPLETED);
}
I noticed that there are people having problems in the use of TextToSpeech to ask that the solution to you
How to know when TTS is finished?
without use setOnUtteranceCompletedListener
public void isTTSSpeaking(){
final Handler h =new Handler();
Runnable r = new Runnable() {
public void run() {
if (!tts.isSpeaking()) {
onTTSSpeechFinished();
}
h.postDelayed(this, 1000);
}
};
h.postDelayed(r, 1000);
}
Try this following code which shows a toast after TTS completed. Replace toast with your own action.
public class MainActivity extends AppCompatActivity implements TextToSpeech.OnInitListener{
private boolean initialized;
private String queuedText;
private String TAG = "TTS";
private TextToSpeech tts;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tts = new TextToSpeech(this /* context */, this /* listener */);
tts.setOnUtteranceProgressListener(mProgressListener);
speak("hello world");
}
public void speak(String text) {
if (!initialized) {
queuedText = text;
return;
}
queuedText = null;
setTtsListener(); // no longer creates a new UtteranceProgressListener each time
HashMap<String, String> map = new HashMap<String, String>();
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "MessageId");
tts.speak(text, TextToSpeech.QUEUE_ADD, map);
}
private void setTtsListener() {
}
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
initialized = true;
tts.setLanguage(Locale.ENGLISH);
if (queuedText != null) {
speak(queuedText);
}
}
}
private abstract class runnable implements Runnable {
}
private UtteranceProgressListener mProgressListener = new UtteranceProgressListener() {
#Override
public void onStart(String utteranceId) {
} // Do nothing
#Override
public void onError(String utteranceId) {
} // Do nothing.
#Override
public void onDone(String utteranceId) {
new Thread()
{
public void run()
{
MainActivity.this.runOnUiThread(new runnable()
{
public void run()
{
Toast.makeText(getBaseContext(), "TTS Completed", Toast.LENGTH_SHORT).show();
}
});
}
}.start();
}
}; }
With this code I solved the problem. I wanted the start button to stay lit as long as someone was speaking. Maybe this will help someone.
public void _tts_speak_lenght() {
t2 = new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (TTS.isSpeaking()) {
isSpeaking = true;
}
else {
if (!TTS.isSpeaking()) {
t2.cancel();
isSpeaking = false;
imgBtn_startReader.setImageResource(R.drawable.ic_start_off);
}
}
}
});
}
};
_timer.scheduleAtFixedRate(t2, (int)(0), (int)(100));
}
use a SpeakableListener when do text to speak.
private volatile boolean finished;
private SpeakableListener listener = new SpeakableListener() {
#Override
public void markerReached(SpeakableEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void speakableCancelled(SpeakableEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void speakableEnded(SpeakableEvent arg0) {
TestSpeaker.this.finished = true;
}
#Override
public void speakablePaused(SpeakableEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void speakableResumed(SpeakableEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void speakableStarted(SpeakableEvent arg0) {
TestSpeaker.this.finished = false;
}
#Override
public void topOfQueue(SpeakableEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void wordStarted(SpeakableEvent arg0) {
// TODO Auto-generated method stub
}
};
/** Speak the following string. */
public void sayIt(String str) {
System.out.print(" " + str + " ");
/* The the synthesizer to speak. */
synthesizer.speakPlainText(str, listener);
I'm really struggling with something... I have a couple of sentences that I want to read, both verbally through tts speek function, and via text on screen, one sentence at a time.
I have the textview area ready, but putting it together is what I'm not getting. Either it will read all the sentences and only show the last one, or it will show and read only the first sentence.
Anyone know i how I can accomplish this goal?
I just ran into this issue, according to the speak method, use an UtteranceProgressListener. I found out this is not executed on the UI thread, so I had to use runOnUiThread() to get back to update the activity.
tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onStart(String utteranceId) {
}
#Override
public void onDone(String utteranceId) {
LettersActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// Do something on UI thread
}
});
}
#Override
public void onError(String utteranceId) {
Log.e(TAG, "error on " + utteranceId);
}
});
boolean speakingEnd = tts.isSpeaking();
do{
speakingEnd = tts.isSpeaking();
} while (speakingEnd);
//Continue with code
public void speak(String message){
tts.speak(message, TextToSpeech.QUEUE_FLUSH, null);
while (tts.isSpeaking()){
System.Out.Println("Do something or nothing while speaking..")
}
}
Try this
public class MainActivity extends AppCompatActivity implements TextToSpeech.OnInitListener{
private boolean initialized;
private String queuedText;
private String TAG = "TTS";
private TextToSpeech tts;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tts = new TextToSpeech(this /* context */, this /* listener */);
tts.setOnUtteranceProgressListener(mProgressListener);
speak("hello world");
}
public void speak(String text) {
if (!initialized) {
queuedText = text;
return;
}
queuedText = null;
setTtsListener(); // no longer creates a new UtteranceProgressListener each time
HashMap<String, String> map = new HashMap<String, String>();
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "MessageId");
tts.speak(text, TextToSpeech.QUEUE_ADD, map);
}
private void setTtsListener() {
}
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
initialized = true;
tts.setLanguage(Locale.ENGLISH);
if (queuedText != null) {
speak(queuedText);
}
}
}
private abstract class runnable implements Runnable {
}
private UtteranceProgressListener mProgressListener = new UtteranceProgressListener() {
#Override
public void onStart(String utteranceId) {
} // Do nothing
#Override
public void onError(String utteranceId) {
} // Do nothing.
#Override
public void onDone(String utteranceId) {
new Thread()
{
public void run()
{
MainActivity.this.runOnUiThread(new runnable()
{
public void run()
{
Toast.makeText(getBaseContext(), "TTS Completed", Toast.LENGTH_SHORT).show();
}
});
}
}.start();
}
};
}