I am building an android app and I'm using speech recognition but while the app work just fine with Android 11 and any versions below, I've encountered a roadblock with anything beyond Android 12. Despite investing a considerable amount of time into troubleshooting, the root cause of this issue is unknown to me.
I even attempted to follow the suggestions provided in a related Stack Overflow post Here
Unfortunately, even after following these recommendations the result is the same.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
*************************
initSpeechRecognition(this);
speech.setRecognitionListener(this);
recognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "en");
recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
}
public void initSpeechRecognition(Activity activity) {
String recognitionServiceName = getAvailableVoiceRecognitionService(activity);
if (recognitionServiceName == null)
return;
speech = SpeechRecognizer.createSpeechRecognizer(activity,
ComponentName.unflattenFromString(recognitionServiceName));
Log.i("TEST", recognitionServiceName);
}
public static String getAvailableVoiceRecognitionService(Activity activity) {
final List<ResolveInfo> services = activity.getPackageManager().queryIntentServices(
new Intent(RecognitionService.SERVICE_INTERFACE), 0);
String recognitionServiceName = null;
for (final ResolveInfo info : services) {
String packageName = info.serviceInfo.packageName;
String serviceName = info.serviceInfo.name;
String testRecognitionServiceName = packageName + "/" + serviceName;
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("TEST", name + "::" + service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i("TEST", name + "::Disconnected");
}
};
Intent serviceIntent = new Intent(RecognitionService.SERVICE_INTERFACE);
ComponentName recognizerServiceComponent = ComponentName.unflattenFromString(testRecognitionServiceName);
if (recognizerServiceComponent != null) {
serviceIntent.setComponent(recognizerServiceComponent);
try {
boolean isServiceAvailableToBind = activity.bindService(serviceIntent, connection, Context.BIND_AUTO_CREATE);
if (isServiceAvailableToBind) {
activity.unbindService(connection);
recognitionServiceName = testRecognitionServiceName;
break;
}
} catch (SecurityException e) {
e.printStackTrace();
}
}
}
return recognitionServiceName;
}
and these are the rest of the methods
@Override
public void onBeginningOfSpeech() {
Log.i(VOICE_RECOGNITION, "onBeginningOfSpeech");
}
@Override
public void onBufferReceived(byte[] buffer) {
Log.i(VOICE_RECOGNITION, "onBufferReceived: " + Arrays.toString(buffer));
}
@Override
public void onEndOfSpeech() {
Log.i(VOICE_RECOGNITION, "onEndOfSpeech");
}
@Override
public void onError(int errorCode) {
String errorMessage = getErrorText(errorCode);
Log.d(VOICE_RECOGNITION, "FAILED " + errorMessage);
}
@Override
public void onEvent(int arg0, Bundle arg1) {
Log.i(VOICE_RECOGNITION, "onEvent");
}
@Override
public void onPartialResults(Bundle arg0) {
Log.i(VOICE_RECOGNITION, "onPartialResults");
}
@Override
public void onReadyForSpeech(Bundle arg0) {
Log.i(VOICE_RECOGNITION, "onReadyForSpeech");
}
@Override
public void onResults(Bundle results) {
Log.i(VOICE_RECOGNITION, "onResults");
ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
StringBuilder text = new StringBuilder();
assert matches != null;
for (String result : matches) text.append(result).append("\n");
audioToText.add(text.toString());
Log.i(VOICE_RECOGNITION, String.valueOf(audioToText));
}
@Override
public void onRmsChanged(float rmsdB) {
Log.i(VOICE_RECOGNITION, "onRmsChanged: " + rmsdB);
}
public static String getErrorText(int errorCode) {
String message;
switch (errorCode) {
case SpeechRecognizer.ERROR_AUDIO:
message = "Audio recording error";
audioToText.add("audio recording error");
break;
case SpeechRecognizer.ERROR_CLIENT:
message = "Client side error";
audioToText.add("client side error");
break;
case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
message = "Insufficient permissions";
audioToText.add("insufficient permissions");
break;
case SpeechRecognizer.ERROR_NETWORK:
message = "Network error";
audioToText.add("network error");
break;
case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
message = "Network timeout";
audioToText.add("network timeout");
break;
case SpeechRecognizer.ERROR_NO_MATCH:
message = "No match";
audioToText.add("no audio detected");
break;
case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
message = "RecognitionService busy";
audioToText.add("recognition service busy");
break;
case SpeechRecognizer.ERROR_SERVER:
message = "error from server";
audioToText.add("error from server");
break;
case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
message = "No speech input";
audioToText.add("no speech input");
break;
default:
message = "Didn't understand, please try again.";
audioToText.add("no audio detected");
break;
}
return message;
}
I also have the code for startListening() and stopListening() in their appropriate positions and they are triggered just fine.
here is also my the part of the log that get triggered when the app start listening to the speech
2023-08-25 12:07:55.696 31209-31209 Voice Recognition I onReadyForSpeech
2023-08-25 12:07:55.730 31209-31209 Voice Recognition I onRmsChanged: -2.0
2023-08-25 12:07:58.091 31209-31209 Voice Recognition D FAILED No match
I know the app is working fine on a device with android 10 that I have but not with another device that has android 13 and I know that google had made some changes in the Speech Recognizer in android 12 and 13 but there is no place on the internet that properly show how you can implement the changes to the SpeechService and make it work on android 13 even on the official documentation website there is no single snippet of code to show how to implement speech recognition with android 13.
Could anyone provide insights into this matter or suggest potential solutions? Your assistance would be immensely appreciated.