1. 为什么我们需要预装Google TTS引擎?
如果你做过Android系统定制,特别是针对海外市场或者需要语音播报功能的设备(比如智能音箱、车载中控、智能家居面板),肯定遇到过这个让人头疼的问题:用户拿到新设备,兴冲冲地打开导航或者电子书朗读功能,结果系统弹出一个提示——“需要下载语音数据”。用户必须手动连接网络,等待几十甚至上百兆的语音包下载完成,才能正常使用TTS功能。这个体验,说实话,挺糟糕的。
我遇到过不少客户反馈,他们觉得这是设备的一个“缺陷”。用户可不管这是Google的默认设计还是什么技术限制,他们只关心开箱后能不能立刻、顺畅地使用所有功能。所以,预装Google TTS引擎并实现语音包的预缓存,就成了提升开箱即用体验、减少用户操作步骤的关键一步。
更深一层看,这不仅仅是体验问题。对于很多嵌入式设备或行业定制设备,它们可能处于网络环境不稳定,甚至完全离线的状态。如果TTS功能依赖首次联网下载,那这个功能基本就形同虚设了。因此,在系统构建阶段,就把Google TTS引擎(APK)和所需语言的语音数据包(比如中文普通话、美式英语)直接打包进系统镜像,并配置为默认引擎,就成了一项非常实用的系统级定制工作。
简单来说,我们的目标就是:让设备在第一次开机时,TTS功能就已经是“就绪”状态,用户无需任何额外操作。这背后涉及到三个核心动作:预装APK、设为默认引擎、预缓存语音包。接下来,我就把这几年踩过的坑和总结出来的实战经验,毫无保留地分享给你。
2. 系统层修改:让Google TTS成为“天选之子”
要让系统一启动就认准Google TTS,我们需要在Android框架层动几个小手术。别担心,步骤很清晰,跟着做就行。
2.1 修改框架核心:TextToSpeech.java
这是最根本的一步。Android系统内部有一个硬编码的默认TTS引擎常量,在AOSP(Android开源项目)里,它通常是com.svox.pico,也就是那个古老的Pico TTS。我们的任务就是把它替换成Google TTS的包名。
找到文件:frameworks/base/core/java/android/speech/tts/TextToSpeech.java
你需要定位到DEFAULT_ENGINE这个静态常量的定义处。通常它看起来像这样,并且被标记为@Deprecated(谷歌不推荐直接使用,但系统初始化时还是会参考它):
/**
* @deprecated Do not use directly.
*/
@Deprecated
public static final String DEFAULT_ENGINE = "com.svox.pico";
我们要做的就是把这行修改为:
/**
* @deprecated Do not use directly.
*/
@Deprecated
public static final String DEFAULT_ENGINE = "com.google.android.tts";
这里有个非常重要的细节: 我建议采用“覆盖”而非“删除再添加”的方式。也就是说,保留原始的@Deprecated注解和com.svox.pico的定义,但在其下方添加我们修改后的常量。同时,你可以把@Deprecated移到原始定义上,而让我们新的常量不被弃用标记。这样做的目的是保持最好的向后兼容性,以防系统其他部分有特殊逻辑依赖这个弃用状态。
// 原始定义,保持不动,但明确已弃用
@Deprecated
public static final String DEFAULT_ENGINE_LEGACY = "com.svox.pico";
// 我们新的默认引擎定义
public static final String DEFAULT_ENGINE = "com.google.android.tts";
当然,如果你们团队的代码规范允许,直接修改原始常量的值是最彻底的。修改后,需要重新编译framework模块。这个修改确保了系统在寻找默认TTS引擎时,首先指向Google TTS。
2.2 配置默认值资源:defaults.xml
仅仅修改框架代码还不够,因为系统设置(Settings)中的默认值是通过SettingsProvider来初始化的。我们需要在资源文件中定义这个默认值。
找到文件:frameworks/base/packages/SettingsProvider/res/values/defaults.xml
在这个文件的<resources>标签内,添加一个字符串资源:
<string name="default_tts_engine" translatable="false">com.google.android.tts</string>
注意两个关键点:
translatable="false":这个属性必须加上,表明这个字符串不需要被翻译成其他语言。它是一个固定的包名标识符。- 值必须精确匹配:
com.google.android.tts是Google TTS引擎的标准包名,一个字母都不能错。
2.3 注入数据库持久化配置:DatabaseHelper.java
现在我们已经有了资源定义,接下来需要在系统首次启动或数据库升级时,将这个默认值写入系统的安全设置(Secure Settings)数据库中。这个操作是由SettingsProvider完成的。
找到文件:frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
在这个类中,你需要找到loadSecureSettings方法。这个方法负责向secure表里插入一系列默认设置。我们需要在适当的位置插入一行代码,来加载我们刚刚定义的TTS默认引擎。
通常,你会在一个


385

被折叠的 条评论
为什么被折叠?



