1
0
Fork 0

fixed ClassNotFoundException: Didn't find class "android.speech.RecognitionSupportCallback" on Sonim XP3800 and possibly other old devices

This commit is contained in:
sspanak 2025-05-13 12:50:48 +03:00 committed by Dimo Karaivanov
parent e20f1df2db
commit fe0d09eb28

View file

@ -10,6 +10,7 @@ import android.speech.SpeechRecognizer;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import io.github.sspanak.tt9.R;
@ -38,7 +39,7 @@ public class VoiceInputOps {
ConsumerCompat<VoiceInputError> onError
) {
listener = new VoiceListener(ims, onStart, this::onStop, this::onError);
recognizerSupport = DeviceInfo.AT_LEAST_ANDROID_13 ? new SpeechRecognizerSupportModern(ims) : new SpeechRecognizerSupportLegacy(ims);
recognizerSupport = lazyLoadSupportClass(ims);
onStopListening = onStop != null ? onStop : result -> {};
onListeningError = onError != null ? onError : error -> {};
@ -47,6 +48,30 @@ public class VoiceInputOps {
}
/**
* Android normally loads all classes even if they are not used on specific version. This here
* prevents the following error on older devices like Sonim XP3800:
* java.lang.NoClassDefFoundError: Failed resolution of: Landroid/speech/RecognitionSupportCallback;
* Caused by: java.lang.ClassNotFoundException: Didn't find class "android.speech.RecognitionSupportCallback"
*
*/
private SpeechRecognizerSupportLegacy lazyLoadSupportClass(Context context) {
if (DeviceInfo.AT_LEAST_ANDROID_13) {
try {
Package voicePackage = SpeechRecognizerSupportLegacy.class.getPackage();
String className = voicePackage != null ? voicePackage.getName() + ".SpeechRecognizerSupportModern" : "";
Class<?> clazz = Class.forName(className);
Constructor<?> ctor = clazz.getDeclaredConstructor(Context.class);
return (SpeechRecognizerSupportLegacy) ctor.newInstance(context);
} catch (Exception e) {
return new SpeechRecognizerSupportLegacy(context);
}
}
return new SpeechRecognizerSupportLegacy(context);
}
static String getLocale(@NonNull Language lang) {
return lang.getLocale().toString().replace("_", "-");
}