Expo+React Native集成@react-native-voice/voice遇错求助
解决方案:Expo中@react-native-voice/voice初始化失败与版本冲突问题
问题根源
你遇到的TypeError: null is not an object (evaluating 'Voice.startSpeech')本质是原生模块未正确初始化,结合expo doctor检测到的版本冲突,核心原因是@react-native-voice/voice依赖的旧版@expo/config-plugins与当前Expo SDK要求的高版本不兼容,导致插件无法完成原生配置链接。
方案一:用patch-package修改依赖约束(推荐)
通过补丁工具修改@react-native-voice/voice的版本限制,使其适配当前项目的@expo/config-plugins版本:
- 安装补丁工具:
npm install patch-package --save-dev
- 打开
node_modules/@react-native-voice/voice/package.json,修改peerDependencies中的@expo/config-plugins版本为你的项目要求的版本(比如^5.0.2):
"peerDependencies": { "@expo/config-plugins": "^5.0.2", // 其他依赖保持不变 }
- 生成并保存补丁文件:
npx patch-package @react-native-voice/voice
- 清除Expo缓存并重启项目:
npx expo start --clear
方案二:完善配置并重新链接
如果补丁方案无效,检查并补充项目核心配置:
- 添加权限声明:在
app.json/app.config.js中配置录音和语音识别权限:
{ "expo": { "permissions": ["RECORD_AUDIO"], "ios": { "infoPlist": { "NSSpeechRecognitionUsageDescription": "需要访问语音识别功能转换语音为文字", "NSMicrophoneUsageDescription": "需要访问麦克风录制语音" } }, "android": { "permissions": ["RECORD_AUDIO"] } } }
- 注册config插件:在
app.json的plugins数组中添加插件声明:
{ "expo": { "plugins": ["@react-native-voice/voice"] } }
- 重装依赖并清除缓存:
rm -rf node_modules package-lock.json npm install npx expo start --clear
方案三:切换到Expo官方语音识别API
若上述方案仍无法解决,可尝试Expo官方提供的expo-speech-recognition(需联网,部分地区可能受限):
- 安装依赖:
npx expo install expo-speech-recognition
- 核心代码示例:
import { useState, useEffect } from 'react'; import { View, Button, Text } from 'react-native'; import * as SpeechRecognition from 'expo-speech-recognition'; export default function App() { const [recognizedText, setRecognizedText] = useState(''); const [isListening, setIsListening] = useState(false); useEffect(() => { async function requestPermissions() { const { status } = await SpeechRecognition.requestPermissionsAsync(); if (status !== 'granted') { alert('需要开启麦克风和语音识别权限'); } } requestPermissions(); }, []); const startListening = async () => { setIsListening(true); await SpeechRecognition.startListeningAsync({ language: 'en-NZ', onResult: (result) => { setRecognizedText(result.transcriptions[0]?.transcription || ''); }, }); }; const stopListening = async () => { await SpeechRecognition.stopListeningAsync(); setIsListening(false); }; return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Button title={isListening ? '停止识别' : '开始语音转文字'} onPress={isListening ? stopListening : startListening} /> <Text style={{ marginTop: 20 }}>{recognizedText}</Text> </View> ); }
内容的提问来源于stack exchange,提问作者Cimo
相关产品推荐
相关产品推荐

