Android 调用TTS引擎过程及问题记录
前言
背景是需要在华为平板上部署一个能够进行相关中文语音提示的APP,华为系统为鸿蒙3.0,对应Android API 12.
Android 调用TTS引擎
调用TTS引擎之前,首先要确认自己的设备中是否安装了相关的文本转语音引擎以及是否支持中文,查看方法为“设置->辅助功能->无障碍->文本转语音”,鸿蒙系统是这个路径,或者可以直接在设置中直接搜索文本转语音项,如下图所示,点击信息按钮即可对引擎进行语言选择等配置,我这里是因为语音播报没成功,一直怀疑是华为的引擎不行,然后安装了Google的引擎,后来问题解决后发现华为的语音引擎也是可以的,错怪了错怪了。如果没有可支持的语音引擎的话,还可以安装其他国产语音引擎,不过不知道要不要收费。
具体的调用代码比较简单,如下:
重写onInit方法:
mTextToSpeech = new TextToSpeech(this, new TextToSpeech.OnInitListener() { @Override public void onInit(int status) { if (status == SUCCESS) { if (mTextToSpeech.getEngines().size() <= 0) { Toast.makeText(MainActivity.this, "Please install the voice engine", Toast.LENGTH_SHORT).show(); Log.i("tts_engine", "未安装TTS引擎"); return; } //The default language is Chinese int result = mTextToSpeech.setLanguage(Locale.CHINA); if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { Toast.makeText(MainActivity.this, "Chinese is not supported", Toast.LENGTH_SHORT).show(); //Set to English when Chinese is not supported mTextToSpeech.setLanguage(Locale.US); } else { ttsInitFlag = 1;// mTextToSpeech.speak(SPEED_LIMIT_MSG, TextToSpeech.QUEUE_FLUSH, null, null); } } else { Log.e(TAG, "onInit: TextToSpeech initialization failed"); } } });
调用speak:
mTextToSpeech.setPitch(1.0f);//方法用来控制音调mTextToSpeech.setSpeechRate(0.8f);//用来控制语速// 播放语音提示if (ttsInitFlag == 1){ int code = mTextToSpeech.speak(SPEED_LIMIT_MSG, TextToSpeech.QUEUE_ADD, null, null); Log.i("tts_speak", "Speak Result" + code);}
onDestory里添加TTS的销毁:
if (null != mTextToSpeech){ mTextToSpeech.stop(); mTextToSpeech.shutdown(); mTextToSpeech = null;}
就可以了,具体关于TTS的相关函数说明,大家可以自行查找API进行查看。
问题记录
如果发现语音播报失败,还是那句话,一定要学会看日志,找到问题所在,不然直接搜语音播报失败,病急乱投医,浪费时间(我之前就是这么做的,切记切记)。通过在AS的LogCat中搜索TextToSpeech相关的日志,我发现在调用Speak方法时会提示“speak failed: not bound to TTS engine”或“speak failed: TTS engine connection not fully set up”,这个问题通常是因为TextToSpeech服务未能成功启动或者初始化未完成导致的,所以我们要在TTS服务完全启动之后再调用Speak方法,看到网上好多人说要在OnInit方法中调用speak函数,治标不治本,谁会APP初始化的时候调用语音播报,肯定都是在OnInit外部调用,之所以都说要在OnInit中调用,是因为TTS服务初始化完成的一个标志就是,setLanguage()后返回非LANG_MISSING_DATA或LANG_NOT_SUPPORTED,所以在setLanguage后加个判断即可,在调用语音播报时,再判断下当前TTS服务是否初始化即可,我上面的代码中便体现了这一点,某种意义上来说,这确实不算个bug,就是调用时序的问题,除非APP刚运行时就要播报语音(当然我测试语音播报功能时就是这样测试的,所以一直没出声。。)
看网上还有一个额外要注意的地方,需要在AndroidManifest.xml中添加:
<manifest... <queries> <intent> <action android:name="android.intent.action.TTS_SERVICE" /> </intent> </queries> ...</manifest>
好像适用于Android API 11,我的是API 12,没用到这个,也记录一下。
来源地址:https://blog.csdn.net/qq_35308053/article/details/130679901