React Native Voice Speech to Text Not Working on Android: Fixes for Recent Updates
React Native Voice speech-to-text failures on Android after recent updates are caused by Android permission changes, API updates, or native module misconfigurations—not by the core React library itself.
When react-native-voice stops functioning on Android following a React Native or Android SDK upgrade, the issue typically stems from breaking changes in the Android ecosystem rather than the core facebook/react repository. The core React library is a JavaScript UI layer that relies on separate native modules for platform-specific functionality like speech recognition.
Why the Core React Repository Isn't the Source
The facebook/react repository contains the cross-platform JavaScript reconciliation engine and renderer. It does not include Android-specific native modules for microphone access or speech recognition. These capabilities are implemented in the separate React Native codebase or in third-party packages like react-native-voice.
In the React Native architecture, native modules communicate with JavaScript through the bridge. The DeviceEventManagerModule.java file in packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/core/ illustrates how native events are emitted to JavaScript, while ReactPackage.java in the same directory shows how native modules are registered. However, the actual speech recognition implementation resides in react-native-voice’s VoicePackage.java and its interaction with Android’s SpeechRecognizer API.
Common Causes of React Native Voice Android Failures After Updates
Android Permission Changes (API 31+)
Recent Android versions (API level 31 and above) enforce stricter permission models. The RECORD_AUDIO permission must be requested at runtime, and if your app continues listening while backgrounded, you may also need FOREGROUND_SERVICE permissions.
Google Speech API and SpeechRecognizer Updates
Android’s built-in SpeechRecognizer has undergone API changes in recent platform releases. Older callback signatures may be ignored by the system, causing the module to appear unresponsive even when permissions are correct.
Breaking Changes in react-native-voice Package
Major version updates of react-native-voice (version 4.0+) renamed several methods and changed event structures. For example, onSpeechResults behavior was modified to better align with onSpeechPartialResults, requiring updates to your event handlers.
Proguard and R8 Code Stripping
Release builds using Proguard or R8 may aggressively remove classes they deem unused, including the native voice module’s Java classes. This results in "module not found" errors or silent failures in production builds only.
AndroidX and Support Library Mismatches
React Native 0.73+ fully migrated to AndroidX. If your project or third-party dependencies still reference legacy support libraries, the native module may fail to link or compile.
React Native Module Registration Changes
Upgrading React Native changes how native modules are registered. Older manual linking in MainApplication.java differs from the autolinking behavior in React Native 0.60+, and TurboModule architecture in newer versions requires additional configuration.
Implementing Runtime Permissions for Android
Before initializing speech recognition, request the RECORD_AUDIO permission at runtime. This example uses React Native’s PermissionsAndroid API:
import {PermissionsAndroid, Platform} from 'react-native';
async function requestAudioPermission() {
if (Platform.OS !== 'android') return true;
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
{
title: 'Microphone Permission',
message: 'This app needs microphone access to convert speech to text.',
buttonPositive: 'OK',
},
);
return granted === PermissionsAndroid.RESULTS.GRANTED;
}
Call this function before Voice.start() to ensure the user has granted access.
Configuring react-native-voice for Android Stability
Ensure your implementation handles the updated event callbacks and that your build configuration preserves the necessary classes.
Basic Implementation with Updated Event Handlers
import Voice from '@react-native-voice/voice';
import {useEffect, useState} from 'react';
import {Button, Text, View} from 'react-native';
export default function SpeechToText() {
const [isListening, setIsListening] = useState(false);
const [transcript, setTranscript] = useState([]);
useEffect(() => {
Voice.onSpeechStart = () => setIsListening(true);
Voice.onSpeechEnd = () => setIsListening(false);
Voice.onSpeechResults = (e) => setTranscript(e.value);
Voice.onSpeechError = (e) => console.error(e);
return () => {
Voice.destroy().then(Voice.removeAllListeners);
};
}, []);
const toggleListening = async () => {
if (isListening) {
await Voice.stop();
} else {
const hasPermission = await requestAudioPermission();
if (hasPermission) {
await Voice.start('en-US');
}
}
};
return (
<View>
<Button
title={isListening ? 'Stop Listening' : 'Start Listening'}
onPress={toggleListening}
/>
{transcript.map((text, index) => (
<Text key={index}>{text}</Text>
))}
</View>
);
}
Proguard Configuration for Release Builds
Add these rules to android/app/proguard-rules.pro to prevent R8 from stripping the voice module classes:
-keep class com.facebook.react.modules.voice.** { *; }
-keep class com.google.android.gms.** { *; }
-dontwarn com.facebook.react.modules.voice.**
Summary
- The core React repository (
facebook/react) does not contain native speech recognition code; the issue lies in the React Native ecosystem or third-party packages. - Android permission changes in API 31+ require runtime
RECORD_AUDIOrequests and potentiallyFOREGROUND_SERVICEdeclarations. - API changes in Android’s
SpeechRecognizerand breaking changes inreact-native-voice≥4.0 require updated event handlers. - Proguard/R8 may strip native module classes in release builds, requiring specific keep-rules in
android/app/proguard-rules.pro. - AndroidX migration in React Native 0.73+ can cause linking failures if dependencies still use legacy support libraries.
Frequently Asked Questions
Is this a bug in the core React library?
No. The facebook/react repository contains the JavaScript UI reconciliation engine, not platform-specific native modules. Speech recognition functionality is implemented in the separate React Native codebase or third-party packages like react-native-voice. The native module registration in React Native occurs through files like ReactPackage.java, but the actual speech logic resides in external packages.
Why did speech to text stop working after upgrading to React Native 0.73+?
React Native 0.73 completed the migration to AndroidX, replacing legacy support libraries. If your react-native-voice installation or other dependencies still reference old support library classes, the native module fails to link. Additionally, newer React Native versions use TurboModule architecture, which requires packages to update their native module registration from the older ReactPackage interface to the new TurboReactPackage implementation.
Do I need to update Proguard rules for release builds?
Yes. If speech-to-text works in development but fails in production Android builds, Proguard or R8 is likely stripping the native module classes. Add the keep-rules to android/app/proguard-rules.pro to preserve com.facebook.react.modules.voice.** and com.google.android.gms.** classes. Without these rules, the JavaScript bridge cannot locate the native implementation at runtime.
How do I verify if the native module is correctly linked?
Check your MainApplication.java (or MainApplication.kt) for manual package listings if using React Native <0.60. For React Native ≥0.60, verify autolinking by running ./gradlew :app:dependencies and confirming react-native-voice appears in the dependency tree. Additionally, check the Android build logs for "Native module Voice tried to override Voice" warnings, which indicate duplicate registrations, or "Could not find generated setter for class" errors, which indicate the module isn't properly registered in the ReactPackage list.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →