第六章 语音交互集成:让车真正“听懂”人话

语音交互,说白了就是给车装上“耳朵”和“嘴巴”。

我最早做车载项目时,客户提了个需求:“用户说‘我冷了’,空调得自动升温。”听起来简单吧?但真正落地时,你会发现坑多得很——语音识别不准、反馈延迟、唤醒词不灵敏……嗯,这一章咱们就把这些硬骨头啃下来。

6.1 Google Assistant 集成:站在巨人肩膀上

Android Automotive 原生支持 Google Assistant,这是最省力的方案。你想想看,Google 已经帮你处理了语音识别、自然语言理解、对话管理,你只需要做两件事:

  • 在车机系统里注册 Assistant 服务
  • 定义你的车载 App 能响应哪些意图(Intent)

我在项目中遇到过最典型的问题:Google Assistant 能听懂“导航到公司”,但听不懂“打开座椅加热”。为什么?因为后者不是 Google 预定义的意图,需要你自己扩展。

核心集成步骤:

  1. 在 AndroidManifest.xml 中声明 Assistant 权限
  2. 实现 Assistant 回调接口
  3. 注册自定义 App 动作(App Actions)
// 注册 Google Assistant 回调
public class MyAssistantService extends AssistantService {
    @Override
    public void onHandleScreenshot(ScreenshotRequest request) {
        // 处理屏幕截图请求
    }

    @Override
    public void onHandleAssistantVoice(AssistantVoiceRequest request) {
        // 处理语音输入
        String userQuery = request.getVoiceQuery();
        // 解析并执行
    }
}

我的经验:不要一股脑把所有功能都交给 Assistant。像空调控制、车窗升降这类高频操作,建议走自定义语音通道,响应速度能快 200-300ms。用户对延迟很敏感,超过 1 秒就会觉得“卡”。

6.2 自定义语音命令:让车听懂你的“黑话”

Google Assistant 再强,也听不懂“把风量调大两档”这种车载场景特有的指令。这时候就需要自定义语音命令了。

我习惯的做法是:先用 Google 的 SpeechRecognizer 做语音转文字,然后自己写一个意图匹配引擎。

// 自定义语音命令解析
public class CustomVoiceCommandParser {
    private static final Map<String, String> COMMAND_MAP = new HashMap<>() {{
        put("调大风量", "AC_FAN_UP");
        put("风量大一点", "AC_FAN_UP");
        put("热死了", "AC_TEMP_DOWN");
        put("冷死了", "AC_TEMP_UP");
    }};

    public String parseCommand(String voiceText) {
        for (Map.Entry<String, String> entry : COMMAND_MAP.entrySet()) {
            if (voiceText.contains(entry.getKey())) {
                return entry.getValue();
            }
        }
        return null; // 未匹配
    }
}

你可能会问:“为什么不用机器学习?”说实话,车载场景的指令集是有限的,用规则引擎反而更可靠。我曾经试过用 NLP 模型,结果用户说“我有点热”和“热得受不了”被识别成两个意图……最后还是回归规则匹配。

避坑指南:我曾经把“打开车窗”和“打开天窗”的语音指令写得太像,结果用户说“开窗”,系统随机打开一个。后来我强制要求:必须包含“车窗”或“天窗”关键字,否则弹窗让用户确认。虽然多了一步交互,但避免了误操作。

6.3 语音反馈与 TTS:让车会“说话”

车不能光听不说。用户说“调高温度”,你得回一句“好的,温度已调高至 26 度”。这就是 TTS(Text To Speech)的活儿。

Android Automotive 内置了 TTS 引擎,但默认的语音太机械了。我建议用第三方 TTS 服务,比如百度、科大讯飞的车载版,音色更自然。

// TTS 语音反馈示例
TextToSpeech tts = new TextToSpeech(context, status -> {
    if (status == TextToSpeech.SUCCESS) {
        tts.setLanguage(Locale.CHINESE);
        tts.speak("好的,温度已调高至26度", 
                  TextToSpeech.QUEUE_FLUSH, null, "temp_feedback");
    }
});

反馈设计原则:

  • 简短:一句话说完,别啰嗦。用户不想听“正在为您执行温度调节操作,请稍候”。
  • 确认:必须让用户知道“执行了”还是“没执行”。
  • 容错:没听懂就说“抱歉,我没听清,请再说一遍”。

我记得有一次测试,用户说“导航到天安门”,TTS 回了句“正在为您规划到天安门的路线”。结果用户又说了句“不对,是地安门”。系统没反应过来,直接沉默了。后来我加了个“取消”指令,用户说“取消”就终止当前操作。嗯,这个小改动救了不少场。

6.4 语音唤醒:说句话就能唤醒车机

语音唤醒,就是让车一直“听”着,听到特定关键词就激活。比如“你好,小驰”、“嘿,Google”。

Android Automotive 支持两种唤醒模式:

模式 功耗 响应速度 适用场景
硬件唤醒(DSP) 低(~50mW) 快(<200ms) 熄火/待机状态
软件唤醒(AP) 高(~500mW) 中(<500ms) 车机亮屏状态

我建议:车机亮屏时用软件唤醒,熄火待机时切到硬件唤醒。这样既省电又灵敏。

// 注册唤醒词
public class WakeupService extends Service {
    private static final String WAKEUP_WORD = "你好小驰";

    @Override
    public void onCreate() {
        super.onCreate();
        // 初始化唤醒引擎
        WakeupEngine.init(this, WAKEUP_WORD, () -> {
            // 唤醒成功,启动语音交互
            startVoiceInteraction();
        });
    }
}

注意:唤醒词不要太长,3-4 个字最佳。我曾经见过一个项目用“亲爱的智能助手请帮我”,结果用户说到一半就卡壳了。唤醒词越短,识别率越高。

知识体系总览

下面这张图,是我自己梳理的语音交互集成全流程。你看一眼就能明白各个模块怎么配合:

语音交互集成知识体系 语音输入 唤醒与识别 意图解析 执行层(导航、空调、媒体、车窗...) 反馈层(TTS语音反馈 + UI视觉反馈) 持续监听 → 等待下一次唤醒 循环

从图上你能看到:语音输入进来后,先经过唤醒与识别模块,再解析意图,然后交给执行层处理,最后通过反馈层告诉用户结果。整个过程是闭环的,而且会持续监听下一次唤醒。

我的建议:刚开始做语音交互时,别追求“全功能”。先搞定 3-5 个高频场景(导航、空调、音乐、电话、车窗),跑通整个链路。用户用起来觉得“还行”,你再慢慢加功能。一口吃不成胖子,车载开发尤其如此。

好了,这一章的内容就到这里。语音交互这块,说白了就是“听、懂、做、说”四个字。听要准,懂要快,做要稳,说要自然。你把这四个字琢磨透了,车机语音交互就算入门了。