I have followed several tutorials, but I am experiencing the same problem. First, here is my simple code:
import java.util.Locale;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.util.Log;
public class AchievementsActivity extends Activity implements OnInitListener {
TextToSpeech reader;
Locale canada;
boolean readerInit = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
canada = Locale.ENGLISH;
reader = new TextToSpeech(this, this);
//speak();
// while (reader.isSpeaking()) {} //waiting for reader to finish speaking
}
@Override
public void onStart() {
super.onStart();
//speak();
}
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
reader.setLanguage(canada);
reader.setPitch(0.9f);
Log.e("Init", "Success");
readerInit = true;
speak();
}
else
System.out.println("Something went wrong.");
}
public void speak() {
reader.speak("You currently have no achievements.", TextToSpeech.QUEUE_FLUSH, null);
}
}
Now, notice the first speak in onCreate()
which I have commented out, and the second in onStart()
which I have also commented out. The reason for this is obvious based on what I receive in LogCat. For some reason, they are called before the initialization of the reader
is complete. So the only way I have this working right is by placing the speak()
function immediately after the initialization is sure to complete inside its own method.
So I was wondering if there is any way to wait for the initialization to complete, and then run speak()
in onCreate
or onStart()
.
You can do something like this:
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
reader.setLanguage(canada);
reader.setPitch(0.9f);
Log.e("Init", "Success");
readerInit = true;
// wait a little for the initialization to complete
Handler h = new Handler();
h.postDelayed(new Runnable() {
@Override
public void run() {
// run your code here
speak();
}
}, 400);
}
else {
System.out.println("Something went wrong.");
}
}
It's not very nice, but it works. I hope somebody will find a better solution...
please take a look to this tutorial.
Basically, it forces the init during the onCreate()
method.
// Fire off an intent to check if a TTS engine is installed
Intent checkIntent = new Intent();
checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkIntent, MY_DATA_CHECK_CODE);
Then, you will be able to speech any text you want at the start (with out any interaction from the user). And of course, speak will work.
HTH!
Milton
Try to use another constructor for the TextToSpeech class that using the given TTS engine:
TextToSpeech(this,this,"com.google.android.tts");
Instead of:
new TextToSpeech(this, this);
来源:https://stackoverflow.com/questions/14563098/text-to-speech-not-working-as-expected