Android中TextToSpeech的UtteranceProgressListener回调未触发求助
解决TextToSpeech UtteranceProgressListener回调不触发的问题
我仔细看了你的代码,发现两个核心问题导致UtteranceProgressListener的回调始终没被调用,另外还有一个线程相关的坑需要避开:
1. Utterance ID的传递冲突 + 空ID问题
你同时用了两种方式传递Utterance ID:
- 给
Bundle设置了空字符串的KEY_PARAM_UTTERANCE_ID - 又在
speak()方法的第四个参数传了"MyID"
这两种方式是互斥的,而且空的Utterance ID会导致系统无法识别这个朗读任务,从而不会触发回调。你只需要选择其中一种方式传递非空的唯一ID即可。
2. 回调线程的UI操作限制
UtteranceProgressListener的所有回调方法都是在后台线程执行的,直接在里面调用Toast.makeText()会因为不在UI线程而无法正常显示,甚至可能抛出异常。必须切换到UI线程再执行UI操作。
修正后的完整代码
// 初始化TextToSpeech mtts = new TextToSpeech(myAct, new TextToSpeech.OnInitListener() { @Override public void onInit(int status) { if (status == TextToSpeech.SUCCESS) { int result = mtts.setLanguage(Locale.US); // 额外检查语言是否支持,避免朗读失败 if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { Toast.makeText(myAct, "US English not supported", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(myAct, "TTS initialization failed", Toast.LENGTH_SHORT).show(); } } }); // 设置UtteranceProgressListener mtts.setOnUtteranceProgressListener(new UtteranceProgressListener() { @Override public void onDone(String utteranceId) { // 切换到UI线程显示Toast myAct.runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(myAct, "OnDone called for ID: " + utteranceId, Toast.LENGTH_LONG).show(); } }); } @Override public void onError(String utteranceId) { myAct.runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(myAct, "OnError called for ID: " + utteranceId, Toast.LENGTH_LONG).show(); } }); } @Override public void onStart(String utteranceId) { myAct.runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(myAct, "OnStart called for ID: " + utteranceId, Toast.LENGTH_LONG).show(); } }); } }); // 方式一:只用Bundle传递Utterance ID Bundle params = new Bundle(); params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "MyUniqueID"); // 非空唯一ID myAct.mtts.speak(myText, TextToSpeech.QUEUE_FLUSH, params, null); // 方式二:只用speak方法的第四个参数(推荐,更简洁) // myAct.mtts.speak(myText, TextToSpeech.QUEUE_FLUSH, null, "MyUniqueID");
额外注意事项
- 确保在Activity的
onDestroy()方法中释放TextToSpeech资源:if (mtts != null) { mtts.stop(); mtts.shutdown(); },避免内存泄漏。 - 检查设备是否安装了支持英文的TTS引擎,比如Google Text-to-Speech,有些默认引擎可能不支持
Locale.US。
内容的提问来源于stack exchange,提问作者Fijoy Vadakkumpadan
相关产品推荐
相关产品推荐

