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

Android后台服务中RecognitionListener无响应问题如何解决

代码核心问题&修复方案

  • 错误调用识别启动方法
    你使用startActivity(mSpeechRecognizerIntent)是启动系统自带的语音识别交互界面,并不会触发你绑定的SttListener回调。使用SpeechRecognizer类实现静默识别时,应该调用mSpeechRecognizer.startListening(mSpeechRecognizerIntent)方法启动识别,删除startActivity相关代码。

  • SpeechRecognizer被GC回收
    你将mSpeechRecognizer定义为onStartCommand的局部变量,方法执行完成后该对象会被垃圾回收,后续识别回调没有绑定对象,自然不会触发任何日志。需要将SpeechRecognizer改为Service的全局成员变量。

  • 缺少必要权限与前台服务配置

    1. 语音识别需要RECORD_AUDIO动态权限,你需要先在Activity中申请该权限后再启动服务,否则识别会直接报错。
    2. 安卓10及以上版本,后台获取麦克风权限需要申请FOREGROUND_SERVICE_MICROPHONE权限,同时你的服务必须改为前台服务,在onStartCommand中调用startForeground()绑定通知,否则服务会被系统限制麦克风访问、甚至直接被杀死。
    3. 你当前SttListener的onError只输出固定日志,建议打印error code方便定位问题,比如System.out.println("识别错误:" + error),常见错误码可以参考SpeechRecognizer的ERROR_*常量定义。
  • 唤醒词功能逻辑缺失
    你当前使用的系统SpeechRecognizer是短语音识别方案,只会在启动后监听一次语音输入,识别完成就会停止,无法实现类似"Hey app"的持续唤醒效果。普通第三方应用无法使用系统级的热词唤醒能力,你需要集成第三方语音SDK的唤醒词功能,比如讯飞语音、百度语音的离线唤醒能力,才能实现后台持续监听唤醒词的效果。

核心修正代码片段

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;

import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;

import java.util.ArrayList;

public class SttService extends Service {
    // 改为成员变量,避免被GC回收
    private SpeechRecognizer mSpeechRecognizer;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        System.out.println("I am running!");
        // 安卓8.0以上必须启动前台服务
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("stt_service", "语音识别服务", NotificationManager.IMPORTANCE_LOW);
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
            Notification notification = new NotificationCompat.Builder(this, "stt_service")
                    .setContentTitle("语音识别服务运行中")
                    // 替换为你自己应用的图标资源
                    .setSmallIcon(R.drawable.ic_launcher_foreground)
                    .build();
            startForeground(1, notification);
        }

        mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
        mSpeechRecognizer.setRecognitionListener(new SttListener());

        Intent mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
        // 正确启动监听,不要调用startActivity
        mSpeechRecognizer.startListening(mSpeechRecognizerIntent);

        return START_STICKY;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("A sign");
        return null;
    }

    protected class SttListener implements RecognitionListener {
        @Override
        public void onReadyForSpeech(Bundle params) {
            System.out.println("准备就绪,可以开始说话");
        }

        @Override
        public void onBeginningOfSpeech() {
            System.out.println("检测到用户开始说话");
        }

        @Override
        public void onRmsChanged(float rmsdB) {
            // 音量变化回调,不需要可以留空
        }

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

        @Override
        public void onEndOfSpeech() {
            System.out.println("用户说话结束");
        }

        @Override
        public void onError(int error) {
            // 打印错误码方便排查
            System.out.println("识别错误,错误码:" + error);
        }

        @Override
        public void onResults(Bundle results) {
            // 提取识别结果
            ArrayList<String> result = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
            if (result != null && !result.isEmpty()) {
                System.out.println("识别结果:" + result.get(0));
            }
        }

        @Override
        public void onPartialResults(Bundle partialResults) {
        }

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

    @Override
    public void onDestroy() {
        super.onDestroy();
        // 销毁时释放SpeechRecognizer资源
        if (mSpeechRecognizer != null) {
            mSpeechRecognizer.destroy();
        }
    }
}

额外注意事项

  • 必须先在Activity中动态申请RECORD_AUDIO权限,权限被用户拒绝的情况下识别会直接报错
  • 系统自带的SpeechRecognizer在部分厂商ROM中可能被裁剪或者限制后台调用,若遇到兼容性问题建议替换为第三方语音SDK

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 18:27:01