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

react-native-vosk包后台持续监听语音识别问题求助

React Native Vosk 后台持续语音识别解决方案

权限配置

iOS

在Info.plist中添加以下配置,确保应用能在后台访问麦克风并进行语音识别:

<key>NSMicrophoneUsageDescription</key>
<string>需要访问麦克风进行语音识别</string>
<key>UIBackgroundModes</key>
<array>
  <string>audio</string>
  <string>speech-recognition</string>
</array>

Android

在AndroidManifest.xml中补充必要权限与服务配置:

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_AUDIO" />

<!-- 自定义前台服务的配置 -->
<service
  android:name=".VoiceRecognitionService"
  android:foregroundServiceType="microphone" />

Android 前台服务实现

Android 12+对后台麦克风访问有严格限制,必须将Vosk监听逻辑放在前台服务中,通过通知告知用户应用正在使用麦克风:

  1. 创建前台服务类(VoiceRecognitionService.java):
public class VoiceRecognitionService extends Service {
    private Model model;
    private Recognizer recognizer;
    private MediaRecorder recorder;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // 显示前台通知
        Notification notification = new NotificationCompat.Builder(this, "VOICE_RECOG_CHANNEL")
                .setContentTitle("语音识别中")
                .setContentText("应用正在后台监听语音")
                .setSmallIcon(R.drawable.ic_mic)
                .build();
        startForeground(1, notification);

        // 初始化Vosk
        try {
            model = new Model(this, "model-path");
            recognizer = new Recognizer(model, 16000.0f);
            recorder = new MediaRecorder();
            recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            recorder.setOutputFormat(MediaRecorder.OutputFormat.OGG);
            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.OPUS);
            recorder.setOutputFile("/dev/null");
            recorder.prepare();
            recorder.start();

            // 启动识别监听线程
            new Thread(() -> {
                byte[] buffer = new byte[4096];
                while (!Thread.currentThread().isInterrupted()) {
                    int n = recorder.read(buffer, 0, buffer.length);
                    if (n > 0 && recognizer.acceptWaveForm(buffer, n)) {
                        // 将识别结果发送到RN端
                        sendResult(recognizer.getResult());
                    }
                }
            }).start();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // 释放资源
        if (recorder != null) recorder.stop();
        if (recognizer != null) recognizer.close();
        if (model != null) model.close();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}
  1. 在React Native端启动服务:
import { NativeModules, Platform } from 'react-native';

if (Platform.OS === 'android') {
  NativeModules.IntentLauncher.startService('com.yourpackage.VoiceRecognitionService');
}

iOS 后台音频会话配置

iOS需要保持音频会话激活才能在后台持续监听,使用react-native-audio-session配置音频会话:

import AudioSession from 'react-native-audio-session';

async function setupAudioSession() {
  await AudioSession.configure({
    category: 'playAndRecord',
    mode: 'default',
    options: [
      'mixWithOthers',
      'allowBluetooth',
      'allowAirPlay',
      'defaultToSpeaker',
    ],
  });
  await AudioSession.setActive(true);
}

// 在App启动时调用配置
setupAudioSession();

Vosk 生命周期管理

避免在组件的useEffect中直接初始化Vosk,绑定到App全局生命周期:

import { AppState } from 'react-native';

let recognizer = null;

function initVosk() {
  // 这里写Vosk的初始化逻辑
}

AppState.addEventListener('change', (nextAppState) => {
  if (nextAppState === 'background') {
    // 后台状态下确保recognizer保持运行
    if (!recognizer) initVosk();
  }
});

测试注意事项

  • 必须使用真机测试,模拟器的后台权限和音频功能存在限制
  • 检查设备是否已授予麦克风权限
  • 查看系统日志:Android用adb logcat,iOS用Xcode控制台,排查是否有应用被系统杀死的记录

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 01:11:07