You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在切换Activity前停止RecognitionListener,解决RECOGNIZER_BUSY错误

解决语音识别Activity切换时RECOGNIZER_BUSY错误的方案

这个问题我做语音交互应用时也碰到过,核心原因就是旧Activity的语音识别实例没及时停止并释放资源,导致系统的语音识别服务被占用,新Activity的监听器拿不到资源,就会持续报RECOGNIZER_BUSY错误。下面给你具体的实现方案:

1. 统一管理每个Activity的语音识别实例

每个Activity都要持有独立的SpeechRecognizer实例,同时维护一个标志位跟踪当前是否处于监听状态,方便后续操作判断:

private SpeechRecognizer speechRecognizer;
private boolean isListening = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 初始化语音识别器
    speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
    speechRecognizer.setRecognitionListener(new RecognitionListener() {
        @Override
        public void onReadyForSpeech(Bundle params) {
            isListening = true; // 标记为正在监听
        }

        @Override
        public void onError(int error) {
            isListening = false; // 监听结束或出错时重置标记
            if (error == SpeechRecognizer.ERROR_RECOGNIZER_BUSY) {
                Log.e("SpeechDebug", "识别器被占用,请先释放旧实例");
            }
            // 其他错误逻辑处理...
        }

        @Override
        public void onResults(Bundle results) {
            isListening = false;
            // 处理识别结果...
        }

        // 省略其他必要回调的实现...
    });
}

2. 封装停止监听的通用方法

写一个统一的停止语音识别方法,确保能正确停止当前监听并重置状态:

private void stopSpeechRecognition() {
    if (speechRecognizer != null && isListening) {
        // 停止当前监听请求
        speechRecognizer.stopListening();
        // 如果需要彻底取消所有待处理请求,可以额外调用cancel()
        // speechRecognizer.cancel();
        isListening = false;
    }
}

3. 利用生命周期自动停止监听

当切换Activity时,旧Activity会进入onPause状态,这是最适合停止监听的时机,确保资源被及时释放:

@Override
protected void onPause() {
    super.onPause();
    // 失去焦点时自动停止语音识别
    stopSpeechRecognition();
}

// 保险起见,在Activity销毁时彻底释放识别器资源,避免内存泄漏
@Override
protected void onDestroy() {
    super.onDestroy();
    if (speechRecognizer != null) {
        speechRecognizer.destroy();
        speechRecognizer = null;
    }
}

4. 主动切换时提前停止监听

如果是通过语音指令主动触发Activity切换,可以在启动新Activity前手动调用停止方法,确保万无一失:

// 处理"切换到XX页面"的语音指令
private void handleSwitchActivityCommand() {
    // 先停止当前监听
    stopSpeechRecognition();
    // 再启动目标Activity
    startActivity(new Intent(this, TargetActivity.class));
}

额外注意事项

  • 不要在多个Activity之间共享SpeechRecognizer实例,每个Activity都应该初始化自己的实例,避免资源冲突。
  • 不要在后台长时间保持语音监听,系统会限制这类行为,也容易导致资源占用问题。
  • 确保已经申请了RECORD_AUDIO权限,虽然这不是直接导致RECOGNIZER_BUSY的原因,但权限缺失可能引发其他连锁错误。

内容的提问来源于stack exchange,提问作者edwardffs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:03:54