如何在切换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
相关产品推荐
相关产品推荐

