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

Expo中使用@react-native-voice/voice遇TypeError错误求助

解决TypeError: null is not an object (evaluating 'Voice.startSpeech')错误

错误原因分析

这个错误通常由以下情况导致:

  • 权限未配置或未获取:语音识别依赖麦克风与语音识别权限,未正确申请会导致Voice模块初始化失败
  • Expo环境兼容性问题:@react-native-voice/voice是原生模块,无法在Expo Go客户端直接运行,需额外配置或使用Expo官方语音API
  • 模块初始化不完整:缺少权限请求或必要的初始化步骤

修复方案

方案1:适配Expo环境(推荐,无需EAS构建)

替换第三方模块为Expo官方提供的expo-speech和expo-av,步骤如下:

  1. 安装依赖
npx expo install expo-speech expo-av
  1. 修改代码:
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, Button, View } from 'react-native';
import { useEffect, useState } from 'react';
import * as Speech from 'expo-speech';
import { PermissionStatus, AudioRecorder } from 'expo-av';

export default function App() {
  let [started, setStarted] = useState(false);
  let [results, setResults] = useState([]);

  useEffect(() => {
    // 检查并申请麦克风权限
    async function checkPermissions() {
      const { status } = await AudioRecorder.requestPermissionsAsync();
      if (status !== PermissionStatus.GRANTED) {
        alert('需要麦克风权限才能使用语音识别');
      }
    }
    checkPermissions();
  }, []);

  const startSpeechToText = async () => {
    try {
      await Speech.startRecognitionAsync('zh-CN', {
        onResults: (result) => {
          setResults(result.transcriptions);
          if (result.finished) setStarted(false);
        },
        onError: (error) => {
          console.log('识别错误:', error);
          setStarted(false);
        },
      });
      setStarted(true);
    } catch (error) {
      console.log('启动识别失败:', error);
    }
  };

  const stopSpeechToText = async () => {
    await Speech.stopRecognitionAsync();
    setStarted(false);
  };

  return (
    <View style={styles.container}>
      {!started ? <Button title='Start Speech to Text' onPress={startSpeechToText} /> : null}
      {started ? <Button title='Stop Speech to Text' onPress={stopSpeechToText} /> : null}
      {results.map((result, index) => <Text key={index}>{result}</Text>)}
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

方案2:继续使用@react-native-voice/voice(需EAS构建)

若坚持使用第三方模块,需完成以下配置:

  1. 配置权限
    在app.json(Expo项目)中添加权限声明:
{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSSpeechRecognitionUsageDescription": "需要使用语音识别功能",
        "NSMicrophoneUsageDescription": "需要使用麦克风录制语音"
      }
    },
    "android": {
      "permissions": ["RECORD_AUDIO"]
    }
  }
}
  1. 添加Expo配置插件
    安装并配置模块的compat插件:
npx expo install @react-native-voice/voice

在app.json中添加插件:

{
  "expo": {
    "plugins": ["@react-native-voice/voice"]
  }
}
  1. 修改代码补充权限请求
useEffect(() => {
  async function initVoice() {
    // 先请求权限
    const granted = await Voice.requestPermissions();
    if (!granted) {
      alert('需要麦克风和语音识别权限');
      return;
    }
    // 再绑定监听事件
    Voice.onSpeechError = onSpeechError;
    Voice.onSpeechResults = onSpeechResults;
  }
  initVoice();

  return () => {
    Voice.destroy().then(Voice.removeAllListeners);
  }
}, []);
  1. 使用EAS构建项目
    由于该模块是原生模块,无法在Expo Go运行,需执行构建命令:
eas build --platform android|ios

关键注意点

  • Expo Go仅支持Expo官方维护的模块,第三方原生模块需EAS构建或compat插件适配
  • 语音识别必须同时获取麦克风和语音识别权限(iOS需额外配置权限描述)
  • 调用Voice.start()前必须确保权限已获取,否则会导致模块初始化失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 09:30:57