Android语音识别App无识别结果时崩溃问题求助
Hey there, let's break down why your app crashes when you don't speak after starting the voice listener, and how to fix it:
1. The Root Cause: Incorrect setText() in onError()
The biggest issue in your code is how you handle errors. Right now, you're passing the integer error code directly to textView.setText(error)—but TextView.setText(int) expects a string resource ID, not a raw error number. When no speech is detected, the recognizer triggers errors like ERROR_SPEECH_TIMEOUT (code 8) or ERROR_NO_MATCH (code 7), and since there's no string resource with those IDs, your app throws a Resources.NotFoundException and crashes.
Let's fix this by converting error codes to human-readable messages:
@Override public void onError(int error) { TextView errorTextView = findViewById(R.id.errors); String errorMsg; switch(error) { case SpeechRecognizer.ERROR_AUDIO: errorMsg = "Audio recording failed"; break; case SpeechRecognizer.ERROR_CLIENT: errorMsg = "Client-side error occurred"; break; case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS: errorMsg = "Missing required permissions"; break; case SpeechRecognizer.ERROR_NETWORK: errorMsg = "Network connection error"; break; case SpeechRecognizer.ERROR_NETWORK_TIMEOUT: errorMsg = "Network request timed out"; break; case SpeechRecognizer.ERROR_NO_MATCH: errorMsg = "No speech matches found"; break; case SpeechRecognizer.ERROR_RECOGNIZER_BUSY: errorMsg = "Recognition service is busy"; break; case SpeechRecognizer.ERROR_SERVER: errorMsg = "Server-side error"; break; case SpeechRecognizer.ERROR_SPEECH_TIMEOUT: errorMsg = "No speech input detected"; break; default: errorMsg = "Unknown error: " + error; } errorTextView.setText(errorMsg); }
2. Strengthen Null Checks in onResults()
Your existing checks are a good start, but we can make them more robust to handle edge cases where results might be empty or null:
@Override public void onResults(Bundle results) { TextView spokenTextView = findViewById(R.id.spokenWords); if (results == null) { spokenTextView.setText("No results received"); return; } List<String> resultList = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); if (resultList != null && !resultList.isEmpty()) { spokenTextView.setText(resultList.get(0)); } else { spokenTextView.setText("No valid speech results"); } }
3. About the Missing onNoResults() Method
You're correct—Android's RecognitionListener doesn't have an explicit onNoResults callback. Instead, when no speech is detected or recognized, the system fires the onError method with specific error codes (like the ones we handled above). That's where you'll handle the "no speech" scenario.
4. Quick Optimizations
- Avoid repeated
findViewByIdcalls: Initialize your TextViews once in your Activity'sonCreate()and store them as member variables—this is more efficient than fetching them every time a callback fires. - Check recognition availability first: Before starting the listener, verify if speech recognition is supported on the device:
if (!SpeechRecognizer.isRecognitionAvailable(this)) { Toast.makeText(this, "Speech recognition isn't available on this device", Toast.LENGTH_SHORT).show(); return; }
With these changes, your app will no longer crash when no speech is detected—it'll instead show a clear, user-friendly message explaining what happened.
内容的提问来源于stack exchange,提问作者Rikudou

