Android“说话失败:没有绑定tts引擎”

我的Android应用程序具有文本说话function,并且超过一个活动使用此function。 因此创建了一个静态助手类来简化这一过程。

import java.util.Locale; import android.content.Context; import android.speech.tts.TextToSpeech; import android.speech.tts.TextToSpeech.OnInitListener; import android.util.Log; public class TextToSpeechController implements OnInitListener { private static final String TAG = "TextToSpeechController"; private TextToSpeech myTTS; private String textToSpeak; private Context context; private static TextToSpeechController singleton; public static TextToSpeechController getInstance(Context ctx) { if (singleton == null) singleton = new TextToSpeechController(ctx); return singleton; } private TextToSpeechController(Context ctx) { context = ctx; } public void speak(String text) { textToSpeak = text; if (myTTS == null) { // currently can't change Locale until speech ends try { // Initialize text-to-speech. This is an asynchronous operation. // The OnInitListener (second argument) is called after // initialization completes. myTTS = new TextToSpeech(context, this); } catch (Exception e) { e.printStackTrace(); } } sayText(); } public void onInit(int initStatus) { if (initStatus == TextToSpeech.SUCCESS) { if (myTTS.isLanguageAvailable(Locale.UK) == TextToSpeech.LANG_AVAILABLE) myTTS.setLanguage(Locale.UK); } // status can be either TextToSpeech.SUCCESS or TextToSpeech.ERROR. if (initStatus == TextToSpeech.SUCCESS) { int result = myTTS.setLanguage(Locale.UK); if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { Log.e(TAG, "TTS missing or not supported (" + result + ")"); // Language data is missing or the language is not supported. // showError(R.string.tts_lang_not_available); } else { // Initialization failed. Log.e(TAG, "Error occured"); } } } private void sayText() { // ask TTs to say the text myTTS.speak(this.textToSpeak, TextToSpeech.QUEUE_FLUSH, null); } public void stopTTS() { if (myTTS != null) { myTTS.shutdown(); myTTS.stop(); myTTS = null; } } } 

我正在使用这样的助手类。

 TextToSpeechController.getInstance(this).speak(readableMessage); 

但有时候我会在LogCat上看到像beloew这样的错误。

 "speak:failed not bound to tts engine" 

没有exception抛出但TTS没有引起任何反响。 我意识到如果我从BroadcastReceiver触发活动,我就会收到此错误。 否则,如果从应用程序代码手动打开活动没有问题。

这是BroadcastReceiver代码

 private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String newMessage = intent.getExtras().getString(EXTRA_MESSAGE); String readableMessage = intent.getExtras().getString(READABLE_MESSAGE); Bundle b = new Bundle(); b.putString(EXTRA_MESSAGE, newMessage); b.putString(READABLE_MESSAGE, readableMessage); Intent newIntent = new Intent("android.intent.action.MAIN"); newIntent.setClass(context, Speak.class); newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); newIntent.putExtra("MessageReceived", b); newIntent.putExtra("CallType", CallType.NOTIFICATION); context.startActivity(newIntent); } }; 

您的代码不等待从TextToSpeech类的构造函数返回异步。 你甚至有一个评论说它是异步的。 为什么它总是在接收器中失败而不是我不确定的活动 – 除此之外,作为前台任务的Activity可能具有更高的优先级,并且它恰好在你调用sayText之前完成。

你需要等待调用sayText,直到init调用返回它必须新建一个新TTS对象的情况。

这是我用于文本到语音的代码。 对于我的代码,只需输入speakWords(“说些什么”); 在任何活动中。

 public class VoiceRecognition extends Activity implements OnClickListener, OnInitListener { public static final int VOICE_RECOGNITION_REQUEST_CODE = 1234; public Button speakButton; // TTS object public TextToSpeech myTTS; // status check code public int MY_DATA_CHECK_CODE = 0; // setup TTS public void onInit(int initStatus) { // check for successful instantiation if (initStatus == TextToSpeech.SUCCESS) { if (myTTS.isLanguageAvailable(Locale.US) == TextToSpeech.LANG_AVAILABLE) myTTS.setLanguage(Locale.US); } else if (initStatus == TextToSpeech.ERROR) { Toast.makeText(this, "Sorry! Text To Speech failed...", Toast.LENGTH_LONG).show(); } } /** * Called with the activity is first created. */ @Override public void onCreate(Bundle voiceinput) { super.onCreate(voiceinput); // Inflate our UI from its XML layout description. setContentView(R.layout.voice_recognition); // check for TTS data Intent checkTTSIntent = new Intent(); checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA); startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE); } // speak the user text public void speakWords(String speech) { // speak straight away myTTS.speak(speech, TextToSpeech.QUEUE_FLUSH, null); } public void onClick(View v) { speakWords("hello"; } /** * Handle the results from the recognition activity. */ @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == MY_DATA_CHECK_CODE) { if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) { // the user has the necessary data - create the TTS myTTS = new TextToSpeech(this, this); } else { // no data - install it now Intent installTTSIntent = new Intent(); installTTSIntent .setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA); startActivity(installTTSIntent); } } super.onActivityResult(requestCode, resultCode, data); } @Override protected void onDestroy() { super.onDestroy(); myTTS.shutdown(); }