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,步骤如下:
- 安装依赖
npx expo install expo-speech expo-av
- 修改代码:
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构建)
若坚持使用第三方模块,需完成以下配置:
- 配置权限
在app.json(Expo项目)中添加权限声明:
{ "expo": { "ios": { "infoPlist": { "NSSpeechRecognitionUsageDescription": "需要使用语音识别功能", "NSMicrophoneUsageDescription": "需要使用麦克风录制语音" } }, "android": { "permissions": ["RECORD_AUDIO"] } } }
- 添加Expo配置插件
安装并配置模块的compat插件:
npx expo install @react-native-voice/voice
在app.json中添加插件:
{ "expo": { "plugins": ["@react-native-voice/voice"] } }
- 修改代码补充权限请求
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); } }, []);
- 使用EAS构建项目
由于该模块是原生模块,无法在Expo Go运行,需执行构建命令:
eas build --platform android|ios
关键注意点
- Expo Go仅支持Expo官方维护的模块,第三方原生模块需EAS构建或compat插件适配
- 语音识别必须同时获取麦克风和语音识别权限(iOS需额外配置权限描述)
- 调用
Voice.start()前必须确保权限已获取,否则会导致模块初始化失败
内容的提问来源于stack exchange,提问作者oaschpartie
相关产品推荐
相关产品推荐

