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

Android应用内持续语音识别模块实现问题求助

解决方案:应用内持续语音识别(Java/Kotlin)

核心思路

要实现应用前台时持续监听,核心是绑定Activity生命周期,同时避免直接在onSpeechEnded()中立即重启监听——这会导致SpeechRecognizer状态异常,出现识别失效的情况。正确的做法是在识别完成(成功/失败)后,通过延迟重启来保证识别器状态正常。

Java 实现示例

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.util.Log;

import java.util.List;

public class MainActivity extends Activity {
    private SpeechRecognizer speechRecognizer;
    private Intent recognizerIntent;
    private Handler handler = new Handler();
    private static final long RESTART_LISTEN_DELAY = 500; // 延迟500ms重启,避免状态冲突

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

        // 初始化语音识别器
        speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
        recognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getPackageName());

        speechRecognizer.setRecognitionListener(new RecognitionListener() {
            @Override
            public void onReadyForSpeech(Bundle params) {}

            @Override
            public void onBeginningOfSpeech() {}

            @Override
            public void onRmsChanged(float rmsdB) {}

            @Override
            public void onBufferReceived(byte[] buffer) {}

            @Override
            public void onEndOfSpeech() {}

            @Override
            public void onError(int error) {
                Log.e("SpeechRecog", "Error code: " + error);
                // 错误后重启监听
                restartListening();
            }

            @Override
            public void onResults(Bundle results) {
                List<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
                if (matches != null && !matches.isEmpty()) {
                    String voiceText = matches.get(0);
                    // 处理识别到的文本
                    Log.d("SpeechRecog", "识别结果: " + voiceText);
                }
                // 识别完成后重启监听
                restartListening();
            }

            @Override
            public void onPartialResults(Bundle partialResults) {}

            @Override
            public void onEvent(int eventType, Bundle params) {}
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 回到前台时启动监听
        startListeningSafely();
    }

    @Override
    protected void onPause() {
        super.onPause();
        // 退到后台时停止监听并释放资源
        stopListening();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (speechRecognizer != null) {
            speechRecognizer.destroy();
        }
    }

    private void startListeningSafely() {
        if (speechRecognizer != null && !speechRecognizer.isListening()) {
            speechRecognizer.startListening(recognizerIntent);
        }
    }

    private void stopListening() {
        if (speechRecognizer != null && speechRecognizer.isListening()) {
            speechRecognizer.stopListening();
        }
    }

    private void restartListening() {
        // 先停止当前监听,再延迟重启
        stopListening();
        handler.postDelayed(this::startListeningSafely, RESTART_LISTEN_DELAY);
    }
}

Kotlin 实现示例

如果切换到Kotlin,代码会更简洁,核心逻辑和Java一致:

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.speech.RecognitionListener
import android.speech.RecognizerIntent
import android.speech.SpeechRecognizer
import android.util.Log

class MainActivity : Activity() {
    private lateinit var speechRecognizer: SpeechRecognizer
    private lateinit var recognizerIntent: Intent
    private val handler = Handler()
    private val RESTART_LISTEN_DELAY = 500L

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this)
        recognizerIntent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
            putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
            putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, packageName)
        }

        speechRecognizer.setRecognitionListener(object : RecognitionListener {
            override fun onReadyForSpeech(params: Bundle?) {}
            override fun onBeginningOfSpeech() {}
            override fun onRmsChanged(rmsdB: Float) {}
            override fun onBufferReceived(buffer: ByteArray?) {}
            override fun onEndOfSpeech() {}

            override fun onError(error: Int) {
                Log.e("SpeechRecog", "Error code: $error")
                restartListening()
            }

            override fun onResults(results: Bundle?) {
                results?.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)?.let { matches ->
                    if (matches.isNotEmpty()) {
                        val voiceText = matches[0]
                        Log.d("SpeechRecog", "识别结果: $voiceText")
                    }
                }
                restartListening()
            }

            override fun onPartialResults(partialResults: Bundle?) {}
            override fun onEvent(eventType: Int, params: Bundle?) {}
        })
    }

    override fun onResume() {
        super.onResume()
        startListeningSafely()
    }

    override fun onPause() {
        super.onPause()
        stopListening()
    }

    override fun onDestroy() {
        super.onDestroy()
        speechRecognizer.destroy()
    }

    private fun startListeningSafely() {
        if (!speechRecognizer.isListening) {
            speechRecognizer.startListening(recognizerIntent)
        }
    }

    private fun stopListening() {
        if (speechRecognizer.isListening) {
            speechRecognizer.stopListening()
        }
    }

    private fun restartListening() {
        stopListening()
        handler.postDelayed({ startListeningSafely() }, RESTART_LISTEN_DELAY)
    }
}

关键注意事项

  • 生命周期绑定:在onResume启动、onPause停止,确保只有应用前台时运行,避免后台资源浪费或被系统限制。
  • 延迟重启:添加500ms延迟是为了让SpeechRecognizer完成状态重置,避免连续调用startListening导致的状态异常(这就是你之前失效的主要原因)。
  • 错误处理:所有错误场景都要重启监听,防止因识别超时、无语音输入等情况导致监听中断。
  • 权限申请:别忘了在Manifest中添加android.permission.RECORD_AUDIO权限,并且在运行时动态申请(Android 6.0+)。

内容的提问来源于stack exchange,提问作者Michal.K

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:17:46