标准Android SpeechRecognizer在Google Glass XE16 - XE16.2上完美运行 然后XE17更新突然破坏了所有内容,出现以下错误,并且不再向Listener发送回调:
E/AndroidRuntime(6321): FATAL EXCEPTION: main
E/AndroidRuntime(6321): Process: com.google.glass.voice, PID: 6321
E/AndroidRuntime(6321): java.lang.NullPointerException: VoiceEngine.startListening: voiceConfig cannot be null
E/AndroidRuntime(6321): at com.google.glass.predicates.Assert.assertNotNull(Assert.java:68)
E/AndroidRuntime(6321): at com.google.glass.voice.VoiceEngine.startListening(VoiceEngine.java:650)
E/AndroidRuntime(6321): at com.google.glass.voice.VoiceService$VoiceServiceBinder.startListening(VoiceService.java:116)
E/AndroidRuntime(6321): at com.google.glass.voice.GlassRecognitionService.attachCallback(GlassRecognitionService.java:272)
E/AndroidRuntime(6321): at com.google.glass.voice.GlassRecognitionService.onStartListening(GlassRecognitionService.java:216)
E/AndroidRuntime(6321): at android.speech.RecognitionService.dispatchStartListening(RecognitionService.java:98)
E/AndroidRuntime(6321): at android.speech.RecognitionService.access$000(RecognitionService.java:36)
E/AndroidRuntime(6321): at android.speech.RecognitionService$1.handleMessage(RecognitionService.java:79)
E/AndroidRuntime(6321): at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime(6321): at android.os.Looper.loop(Looper.java:149)
通过反汇编GlassVoice.apk(位于/ system / priv-app /),我能够发现你可以将这两个额外内容添加到SpeechRecognizer的Intent中,它修复了NullPointerException:
//mSpeechIntent.putExtra( GlassSpeechRecognizer.EXTRA_VOICE_CONFIG_NAME, "Toto");
mSpeechIntent.putExtra( "voiceConfigName", "Toto");
//mSpeechIntent.putExtra( GlassSpeechRecognizer.EXTRA_VOICE_COMMANDS, new String[]{"red","green","blue"} );
mSpeechIntent.putExtra( "extraVoiceCommands", new String[] {"red","green","blue"}); // Command phrases allowed!
问题是,当他们将GlassVoice.apk移动到私有空间时,您无法从自己的应用程序加载任何类。我没有找到如何解决这个问题 - 如果你知道如何,将非常感谢帮助!
有了这个,我可以在日志中看到我说话时已经识别出一个短语,但我没有对通常的听众进行任何回调。
一些有趣的日志(单词“red”识别,但没有回调):
I/RecognizerController(1818): attachVoiceInputCallback W/RecognizerController(1818): queueingGrecoListener was null in attachVoiceInputCallback ... I/VoiceEngine[20daf4b4](1818): Hotword recognizer triggered a recognition result ... I/SavedAudioStorage(1818): Saved SavedAudioRecord [id=null, filename=/data/data/com.google.glass.voice/recorded_audio/20140508_171311_197.pcm, recognized=true, synced=false, timestamp=1399594400939, recognizedCommands=red:2000:2620, sampleRate=16000]
我们如何解决这个问题?
用答案编辑!
感谢@pscholl,我找到了一个解决方法。 如果你的应用很简单并且不包含很多罐子,那就看看@pscholl解决方案。
在我的情况下,添加包含数千种方法的GlassVoice-xe17.apk使我的应用程序成为臭名昭着的“64K方法”Android天花板。如果您不知道这个可怕的限制是什么,只需考虑一下由Android(Dalvik VM)重新发明的“MS-DOS中的640K”。
首先,我尝试打开ProGuard,以便通过删除所有未使用的方法缩小我的应用程序:问题是配置是一场噩梦,经过数小时尝试失败后,我仍然遇到意外的课程,神秘的错误。
所以我转向Dex加载,如下所述:https://github.com/mmin18/Dex65536。 问题是GlassVoice.apk包含所有com.google.common包,我也通过Guava使用。在Dex65536解决方案中,类加载器首先从外部APK加载类(很好的黑客,你无法转身),因此它无法正常工作。
我最终编写了一个“类预加载器”,在添加额外的Dex ClassLoader之前调用。如果您对代码感兴趣,请给我留言(但它远非最佳)。
那是艰难而丑陋的!我希望Glass Dev Team能够很快解决语音问题,并提供一个简洁的解决方案 - 不像这个: - )
答案 0 :(得分:1)
使用此处描述的方法在XE17上仍然可以正常工作:Glass voice command nearest match from given list,也许您使用null调用初始setVoiceConfig
答案 1 :(得分:0)
或者,如果你可以回退到android语音识别器。这并不像Glass代码那么优雅。
private void displaySpeechRecognizer() {
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "What is your favorite color (e.g. Red, Blue Green)");
startActivityForResult(intent, SPEECH_REQUEST);
}
private @Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == SPEECH_REQUEST && resultCode == RESULT_OK) {
String results = StringUtils.join(data.getStringArrayListExtra(
RecognizerIntent.EXTRA_RESULTS));
//TODO: your switch based on string results. Not you may need to do a fuzzy match based on confidence scores.
}
}
http://developer.android.com/reference/android/speech/RecognizerIntent.html