Expo React Native中@react-native-voice/voice遇startSpeech为null错误求助
问题描述
使用Expo + TypeScript + @react-native-voice/voice 在React Native应用中实现语音转文本功能时,调用start或stop函数出现以下错误:
TypeError: Cannot read property 'startSpeech' of null TypeError: Cannot read property 'stopSpeech' of null
当前使用Android 13系统,怀疑存在版本兼容性问题,尝试多种方法仍无法解决。
相关代码与配置
语音录制组件代码
import React, { useState } from 'react'; import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import Voice from '@react-native-voice/voice'; const SpeechToText = () => { const [isRecording, setIsRecording] = useState(false); const [speechText, setSpeechText] = useState(''); const onSpeechStartHandler = () => { setIsRecording(true); setSpeechText(''); }; const onSpeechEndHandler = () => { setIsRecording(false); }; const onSpeechResultsHandler = (event: any) => { setSpeechText(event.value[0]); }; const startSpeechToText = async () => { try { await Voice.start('en-US'); onSpeechStartHandler(); } catch (error) { console.log(error); } }; const stopSpeechToText = async () => { try { await Voice.stop(); onSpeechEndHandler(); } catch (error) { console.log(error); } }; return ( <View style={styles.container}> <TouchableOpacity style={styles.button} onPressIn={startSpeechToText} onPressOut={stopSpeechToText} disabled={isRecording} > <Text style={styles.text}>Press and hold to speak</Text> </TouchableOpacity> <Text style={styles.speechText}>{speechText}</Text> </View> ); };
app.json配置
{ "expo": { [....] "android": { "adaptiveIcon": { "foregroundImage": "./assets/images/adaptive-icon.png", "backgroundColor": "#ffffff" }, "permissions": [ "android.permission.RECORD_AUDIO" ] }, "plugins": [ [ "@react-native-voice/voice", { "microphonePermission": "CUSTOM: Allow $(PRODUCT_NAME) to access the microphone", "speechRecognitionPermission": "CUSTOM: Allow $(PRODUCT_NAME) to securely recognize user speech" } ] ] } }
package.json依赖
{ "scripts": { "start": "expo start", "android": "expo start --android", "ios": "expo start --ios", "web": "expo start --web", "test": "jest --watchAll" }, "dependencies": { "@react-native-voice/voice": "^3.2.4", "expo": "~48.0.11", "expo-font": "~11.1.1", "expo-linking": "~4.0.1", "expo-permissions": "^14.1.1", "expo-router": "^1.5.2", "expo-speech": "^11.1.1", "expo-splash-screen": "~0.18.1", "expo-status-bar": "~1.4.4", "expo-system-ui": "~2.2.1", "expo-web-browser": "~12.1.1", "react": "18.2.0", "react-dom": "18.2.0", "react-native": "0.71.6", "react-native-keyboard-aware-scroll-view": "^0.9.5", "react-native-safe-area-context": "4.5.0", "react-native-screens": "~3.20.0", "react-native-vector-icons": "^9.2.0", "react-native-web": "~0.18.10" }, "devDependencies": { "@babel/core": "^7.20.0", "@types/react": "~18.0.14", "@types/react-native": "^0.71.5", "react-test-renderer": "18.2.0", "typescript": "^4.9.4" }, "private": true }
解决方案
1. 修复版本兼容性问题
当前@react-native-voice/voice@3.2.4与Expo 48存在适配缺陷,建议升级到适配版本:
npm install @react-native-voice/voice@3.2.6 # 或 yarn add @react-native-voice/voice@3.2.6
2. 完善权限配置与主动申请
Android 13下除麦克风权限外,语音识别还需联网权限,同时要主动在组件内申请权限:
- 更新
app.json权限:
"android": { "permissions": [ "android.permission.RECORD_AUDIO", "android.permission.INTERNET" ] }
- 在组件中添加权限申请逻辑:
import * as Permissions from 'expo-permissions'; import React, { useState, useEffect } from 'react'; // ... 原有代码 ... useEffect(() => { const requestPermissions = async () => { const [audioPerm, speechPerm] = await Promise.all([ Permissions.askAsync(Permissions.AUDIO_RECORDING), Permissions.askAsync(Permissions.SPEECH_RECOGNITION) ]); if (audioPerm.status !== 'granted' || speechPerm.status !== 'granted') { alert('需授予麦克风和语音识别权限才能使用功能'); } }; requestPermissions(); }, []);
3. 正确初始化Voice事件监听
库底层实例未初始化是导致null错误的核心原因,需注册事件监听器并在组件销毁时清理:
useEffect(() => { // 绑定事件监听 Voice.onSpeechStart = onSpeechStartHandler; Voice.onSpeechEnd = onSpeechEndHandler; Voice.onSpeechResults = onSpeechResultsHandler; // 组件卸载时清理 return () => { Voice.destroy().then(Voice.removeAllListeners); }; }, []);
4. 清除Expo缓存并重建项目
缓存可能导致库未正确链接,执行以下操作:
- 关闭Expo开发服务器
- 清除缓存:
expo r -c
- 重新启动Android项目:
expo start --android
5. 检查Android 13系统权限设置
手动确认应用已获得麦克风权限:打开系统设置 -> 应用 -> 你的应用 -> 权限 -> 麦克风,确保权限处于开启状态。
内容的提问来源于stack exchange,提问作者baronnat theo
相关产品推荐
相关产品推荐

