语音交互集成:Google Assistant Automotive、语音唤醒与识别、TTS语音播报、自定义语音指令
语音交互,说白了就是让车机“听懂人话”。在Android Automotive里,这可不是简单加个麦克风就完事。我最早做车机项目时,以为语音就是调个API,结果被各种场景打得措手不及——高速风噪、空调压缩机声、后排乘客聊天……嗯,今天咱们就把这块硬骨头啃下来。
1. Google Assistant Automotive:原生语音助手怎么用
Google Assistant Automotive是Android Automotive自带的语音助手。它和手机上的Assistant不太一样,专门针对驾驶场景做了优化。比如,它支持“免唤醒”指令,你直接说“导航到公司”就行,不用先喊“Hey Google”。
集成方式很简单,在AndroidManifest.xml里声明权限:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
然后在代码里启动Assistant:
// 启动Google Assistant
Intent intent = new Intent(Intent.ACTION_VOICE_COMMAND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
但这里有个坑——不是所有车机都预装了Google服务。我在国内某车企项目里就遇到过,车机用的是AOSP,没有GMS。这时候你就得自己实现语音识别了。
核心要点:Google Assistant Automotive依赖Google Mobile Services(GMS)。如果你的车机没有GMS,请直接跳到下一节。
2. 语音唤醒与识别:从“你好,小X”开始
语音唤醒,就是让车机一直监听一个关键词,比如“你好,小驰”。一旦检测到,就启动识别流程。
Android Automotive里,我们通常用离线唤醒词引擎。我推荐使用Snowboy或Porcupine,它们都是轻量级的,能在低功耗下运行。
举个例子,用Porcupine实现唤醒:
// 初始化Porcupine
Porcupine porcupine = new Porcupine.Builder()
.setKeyword(Porcupine.BUILT_IN_KEYWORDS.PORCUPINE)
.setSensitivity(0.5f)
.build();
// 开始监听
porcupine.start(new PorcupineCallback() {
@Override
public void onWakeWordDetected() {
// 唤醒成功,启动语音识别
startSpeechRecognition();
}
});
唤醒之后,就是语音识别(ASR)。Android自带的SpeechRecognizer能用,但效果一般。我建议用第三方的,比如讯飞、百度、阿里的SDK。它们支持离线识别,延迟低。
我的经验:在车机上,离线识别比在线识别更重要。因为地下车库、隧道里没信号。我曾经在测试时,车进地库语音就挂了,用户投诉说“这车一进地库就变哑巴”。后来我们强制要求所有语音指令必须支持离线模式。
3. TTS语音播报:让车机开口说话
TTS(Text To Speech)就是把文字变成语音。Android自带的TextToSpeech引擎够用,但音色偏机械。我建议用云端TTS,比如Google Cloud TTS或阿里云TTS,音质更自然。
代码实现很简单:
TextToSpeech tts = new TextToSpeech(context, status -> {
if (status == TextToSpeech.SUCCESS) {
tts.setLanguage(Locale.CHINESE);
tts.speak("导航开始,前方500米右转", TextToSpeech.QUEUE_FLUSH, null, null);
}
});
但要注意播报打断策略。比如,导航说“前方右转”,这时候用户说“关闭导航”,TTS应该立即停止。我见过一个项目,TTS播报时用户说话,结果两个声音混在一起,用户气得拍方向盘。
避坑指南:TTS播报时,一定要监听onUtteranceCompleted回调,确保播报完成后再处理下一条指令。否则会出现“播报一半被截断”的问题。
4. 自定义语音指令:让车机听懂你的业务
Google Assistant只能处理通用指令,比如“打电话”、“导航”。但车机有很多自定义场景,比如“打开座椅加热”、“调亮氛围灯”。这些就需要你自己定义语音指令。
我的做法是:
- 定义指令集:比如“打开XX”、“关闭XX”、“调高XX”。
- 解析意图:用正则或NLP模型提取关键词。
- 执行动作:调用对应的系统API。
举个例子,解析“打开座椅加热”:
String command = "打开座椅加热";
if (command.contains("打开") && command.contains("座椅加热")) {
// 调用座椅加热API
CarPropertyManager manager = (CarPropertyManager) car.getCarManager(Car.PROPERTY_SERVICE);
manager.setIntProperty(VehicleProperty.SEAT_HEATER, 0, 1); // 1表示开启
}
这里有个关键点——指令要模糊匹配。用户可能说“开座椅加热”、“座椅加热打开”、“加热座椅”。你不能只写死一种说法。我习惯用关键词+同义词库来解决。
核心逻辑:自定义语音指令 = 唤醒词 + ASR识别 + 意图解析 + 动作执行。缺一不可。
5. 知识体系总览
下面这张图,是我梳理的语音交互集成全流程。你看一眼,心里就有谱了。
6. 实战中的几个坑
最后,分享几个我踩过的坑:
- 麦克风权限:Android Automotive里,麦克风权限需要动态申请。而且有些车机有多个麦克风,你得选对那个。
- 唤醒词误触发:我遇到过用户听收音机,收音机里说“你好”,结果车机被唤醒了。解决方案是降低灵敏度,或者加入声纹验证。
- TTS语速:开车时语速不能太快,也不能太慢。我建议设置1.0倍速,并且支持用户调节。
- 多语言支持:出口车型必须支持英语、阿拉伯语等。别写死中文。
我的习惯:每次集成语音功能,我都会在实车上录一段噪声样本,然后在安静环境、城市道路、高速三种场景下测试识别率。只有三种场景都达标,我才会发布。
语音交互这块,说白了就是“听清、听懂、执行”。听清靠硬件和唤醒词,听懂靠ASR和NLP,执行靠你的业务逻辑。每一步都有坑,但走通了,用户体验会提升一大截。