typescript - [Android][expo][@react-native-voice/voice] [TypeError: Kan inte läsa egenskapen 'startSpeech' av null]
Jag försöker spela in användarröst och omvandla den till text i en react-native-app, med expo, typescript och @react-native-voice/voice-paketet.
Jag har importerat biblioteket till mitt projekt, men när jag försöker starta start eller stop-funktionen får jag följande fel:
TypeError: Cannot read property 'startSpeech' of null
TypeError: Cannot read property 'stopSpeech' of null
Jag har försökt allt, men jag förstår inte varför biblioteket inte verkar laddas korrekt... Jag använder Android 13. Kanske finns det en versionsinkompatibilitet?
Snälla hjälp, jag hittar inga lösningar...
Här är koden för röstinspelning:
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>
);
};
I app.json, här är min konfiguration:
{
"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"
}
]
]
}
}
här är min 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
}```
Svar #1
Importuttalandet för Voice-modulen saknar en standardimport. Istället för:
import Voice from '@react-native-voice/voice';
det borde vara:
import Voice from '@react-native-voice/voice/dist/voice';
Detta beror på att Voice-modulen exporterar ett standardobjekt med en Voice-egenskap, så vi behöver importera just den egenskapen. Dist/voice-sökvägen anger filen där Voice-egenskapen är definierad.
Dessutom antar onSpeechResultsHandler-funktionen att event-objektet har en value-egenskap, vilket kanske inte är fallet. För att undvika potentiella fel kan vi använda valfri kedjning för att kontrollera om egenskapen finns:
setSpeechText(event?.value?.[0] || '');
Detta sätter speechText-tillståndet till det första objektet i value-arrayen, eller en tom sträng om value-egenskapen eller det första objektet i arrayen är odefinierat.
Felmeddelandet tyder på att Voice-modulen inte är korrekt initialiserad eller inte är tillgänglig vid tiden för att anropa funktionerna startSpeechToText och stopSpeechToText. Detta kan hända om Voice-modulen inte är korrekt importerad eller om den ännu inte är laddad när dessa funktioner anropas.
För att åtgärda detta problem kan du försöka följande:
Se till att @react-native-voice/voice-paketet är installerat och importerat korrekt. Du kan kontrollera package.json-filen för att se om paketet är listat som en beroende och kontrollera import-satsen för att säkerställa att det är stavat korrekt.
Se till att röstmodulen är laddad innan du anropar funktionerna startSpeechToText och stopSpeechToText. Du kan lägga till en kontroll för att se om röstmodulen är laddad innan du anropar dessa funktioner, så här:
const startSpeechToText = async () => {
if (Voice) {
try {
await Voice.start('en-US');
onSpeechStartHandler();
} catch (error) {
console.log(error);
}
}
};
const stopSpeechToText = async () => {
if (Voice) {
try {
await Voice.stop();
onSpeechEndHandler();
} catch (error) {
console.log(error);
}
}
};
Detta kontrollerar om Voice-modulen finns innan start- och stoppmetoderna anropas.
Hoppas det hjälper.
Svar #2
Det är inte importen, din ursprungliga import var bra (
import Voice from "@react-native-voice/voice";) Du använder inbyggda bibliotekmoduler (såsom mikrofontillgång), så det kommer inte att fungera i Expo eller en emulator direkt. Du behöver köra i utvecklingsläge. För Android, använd din mobiltelefon:
- Från terminalen: eas build --profile development --platform android
- Från terminalen: npx expo start --dev-client
- Skanna QR-koden med din enhet
Det borde nu fungera som förväntat.
