TextToSpeech:检查 API < 21 是在线还是离线

TextToSpeech: check if it is on-line or off-line for API < 21

我正在尝试实现一个可以读取不同语言文本的应用程序。令人惊讶的是,当我使用 isLanguageAvailable(Locale loc) 方法时,它 returns true 对于 Google 中的语言尚未下载的 TTS 列表。当我调用 speak() 方法时甚至会播放它们。我得出的结论是,发生这种情况是因为它们是在线声音。

文档表明,您可以通过对语音对象使用方法 getFeatures() 来了解语音是否在线。但是, Voice class 是为 API >= 21 实现的。对于 API < 21,有一个 getFeatures(Locale loc) 方法以及 TextToSpeech class,它应该是 return 具有不同特征描述的字符串数组。我已经在不同的引擎和语言环境上尝试了最后一种方法,我通常得到一个空数组。大概,这是TTS开发者可以填写或不填写的额外信息...

那么,我怎么知道 tts-locale 是否是 API < 21 的在线语言环境?

Google Text to Speech 引擎的独特之处在于,如果用户没有安装额外的 'offline' 下载,它可以使用网络合成语音。

通常要请求这个,你会包括:

put(TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS, String.valueOf(shouldNetwork()));

他们的网络合成语音曾经具有明显更高的质量,但最近随着他们的改进,这一点不那么明显了。

Text to Speech 引擎提供的信息 API < 21 毫无希望且普遍错误,正如您在调用 isLanguageAvailable(Locale loc) 时注意到的那样,大多数引擎的报告都不正确。新的 APIs 试图解决这个问题,因此您将努力 API < 21 获取您可以依赖的详细信息。查看 my answer on this question 以了解如何查询元素。

在撰写本文时,即使使用了新的 APIs,引擎也会提供不正确的信息。

IVONA为例,查询getVoices()时returns类似于:

Voice[Name: en-US, locale: en_US, quality: 300, latency: 300, requiresNetwork: false, features: [embeddedTts]] 

但是省略了:

Voice[Name: en-US, locale: en_US, quality: 300, latency: 300, requiresNetwork: false, features: [embeddedTts, **notInstalled**]] 

因此,您的代码将假定此引擎可以正常工作,但它不会...。这非常令人沮丧,还有我向他们提交的未答复错误报告。

综上所述,您目前可能不得不在第一次尝试与引擎对话时求助于一个简单的通知,当您点击该通知时,会导致您的应用出现常见问题解答 - 在常见问题解答中,您将说明如果引擎不说话,检查安装和下载.......

令人沮丧的是,我无法 post 为您提供一切正常的简单代码片段。