Java Android会一直等到调用文本到语音的OnInit
我有一个问题,文字到语音不能说任何东西。我意识到这是因为我在TTS初始化之前试图调用“Speak()” 我需要等到TTS初始化后,才能成功调用“Speak()”。我认为按照这条思路做一些事情会奏效:Java Android会一直等到调用文本到语音的OnInit,java,android,text-to-speech,Java,Android,Text To Speech,我有一个问题,文字到语音不能说任何东西。我意识到这是因为我在TTS初始化之前试图调用“Speak()” 我需要等到TTS初始化后,才能成功调用“Speak()”。我认为按照这条思路做一些事情会奏效: @Override public void onInit(int status) { if (status == TextToSpeech.SUCCESS) { mTTSInitialised = true; } else { Log.e("TTS",
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
mTTSInitialised = true;
} else {
Log.e("TTS", "Initialisation Failed!");
}
}
...
while(!mTTSInitialised){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
但这根本无法初始化。有没有办法有效地做到这一点?嗯。。
这不是个好主意
您可以尝试将文本添加到TTS队列,并让它完成它的工作。此代码段可以位于按钮单击等内部,如下所示:
tts.speak(toSpeak, TextToSpeech.QUEUE_ADD, null);
这会有帮助。文本到语音引擎的初始化是异步的,这就是为什么您意识到在请求它处理一个话语之前,必须“等待”它完成的原因 即使它最终成功初始化,它也可能随后被系统终止,当然也可能无法初始化,因此在引擎未准备好的情况下,您始终需要准备好处理发言请求 添加以下帮助器类
public class PendingTTS {
private String pendingUtterance;
private int pendingQueueType;
public String getPendingUtterance() {
return this.pendingUtterance;
}
public void setPendingUtterance(@NonNull final String pendingUtterance) {
this.pendingUtterance = pendingUtterance;
}
public int getPendingQueueType() {
return this.pendingQueueType;
}
public void setPendingQueueType(final int pendingQueueType) {
this.pendingQueueType = pendingQueueType;
}
}
假设您使用的是活动
,则需要声明以下变量:
private volatile PendingTTS pendingTTS;
private static final int MAX_INIT_ATTEMPTS = 4;
private volatile int initCount;
并在onCreate()中初始化文本到语音对象
在您的onInitListener
中,您将检查是否有任何悬而未决的演讲:
@Override
public void onInit(final int status) {
switch (status) {
case TextToSpeech.SUCCESS:
initCount = 0;
// Set up tts stuff
tts.setOnUtteranceProgressListener(YOURprogressListener);
if (pendingTTS != null) {
// We have pending speech, process it and check the result
int speechResult = tts.speak(pendingTTS.getPendingUtterance(),pendingTTS.getPendingQueueType(),
// remaining tts variables here)
switch (speechResult){
case TextToSpeech.SUCCESS:
// Result was successful
pendingTTS = null;
break;
case TextToSpeech.ERROR:
// Speech failed
// Check if it has repeatedly failed up to the max attempts
if(initCount < MAX_INIT_ATTEMPTS){
initCount ++;
tts = new TextToSpeech(YOURActivity.this, YOURonInitListener);
} else {
// Totally broken - let the user know it's not working
}
break;
}
} else {
// there was nothing to process
}
break;
case TextToSpeech.ERROR:
// Check if it has repeatedly failed up to the max attempts
if(initCount < MAX_INIT_ATTEMPTS){
initCount ++;
tts = new TextToSpeech(YOURActivity.this, YOURonInitListener);
} else {
// Totally broken - let the user know it's not working
}
break;
}
如果成功,请确保pendingts
设置为空
总体设计是,如果初始化失败,它将尝试再次初始化,直到允许的最大尝试次数。如果语音失败,它将尝试再次初始化发动机,首先设置pendingts
参数
希望您能做到这一点。这是错误的。监听器跟踪演讲,而不是引擎的初始化。我很糟糕,在我创建音频的地方,它随着我的声音流动而摇摆。更新了答案。如果您尝试使用speak(),但它尚未初始化,该怎么办?如果你按照你的建议去做,会不会有相当大的延迟,比如说,点击一个按钮,然后它说话(因为你必须重新初始化并等待onInit被激活?),是否可以做一些类似的事情:检测它是否已经被初始化,如果没有,显示进度对话框,直到它有?@Daniel在任何实现中,您的speak方法都会尝试正常说话。如果返回ERROR
,则需要尝试初始化引擎,然后处理任何挂起的语音,如上所示。在大多数情况下,你会希望它已经被草签,所以它会立即说话。否则,当您的utranceprogresslistener
调用“onStart”时,您可能会在启动初始化和删除初始化之间发出通知
@Override
public void onInit(final int status) {
switch (status) {
case TextToSpeech.SUCCESS:
initCount = 0;
// Set up tts stuff
tts.setOnUtteranceProgressListener(YOURprogressListener);
if (pendingTTS != null) {
// We have pending speech, process it and check the result
int speechResult = tts.speak(pendingTTS.getPendingUtterance(),pendingTTS.getPendingQueueType(),
// remaining tts variables here)
switch (speechResult){
case TextToSpeech.SUCCESS:
// Result was successful
pendingTTS = null;
break;
case TextToSpeech.ERROR:
// Speech failed
// Check if it has repeatedly failed up to the max attempts
if(initCount < MAX_INIT_ATTEMPTS){
initCount ++;
tts = new TextToSpeech(YOURActivity.this, YOURonInitListener);
} else {
// Totally broken - let the user know it's not working
}
break;
}
} else {
// there was nothing to process
}
break;
case TextToSpeech.ERROR:
// Check if it has repeatedly failed up to the max attempts
if(initCount < MAX_INIT_ATTEMPTS){
initCount ++;
tts = new TextToSpeech(YOURActivity.this, YOURonInitListener);
} else {
// Totally broken - let the user know it's not working
}
break;
}
pendingTTS = new PendingTTS();
pendingTTS.setPendingQueueType(// your queue type);
pendingTTS.setPendingUtterance(// your utterance);