语音识别-在谷歌眼镜XE17更新后,语音识别器坏了-如何解决



标准Android语音识别器在Google Glass XE16 - XE16.2上运行良好
然后,XE17更新突然破坏了一切,出现以下错误,不再回调监听器:

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/private -app/),我能够发现你可以将这两个额外的添加到你的语音识别器的意图,它修复了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",但没有回调):

<>之前我/RecognizerController (1818): attachVoiceInputCallbackW/RecognizerController(1818): queueinggrerecolistener在attachVoiceInputCallback中为空…I/VoiceEngine[20daf4b4](1818):热词识别器触发一个识别结果…I/SavedAudioStorage(1818): Saved SavedAudioRecord [id=null, filename=/data/data/com.google.glass.voice/recorded_audio/20140508_171311_197. log]pcm, recognized=true, synced=false, timestamp=1399594400939, recognizedCommands=red:2000:2620, sampleRate=16000]之前

我们如何解决这个问题?



编辑答案!

感谢@pscholl,我找到了一个解决方案。如果你的应用程序很简单,并且不包含很多jar文件,只需查看@pscholl解决方案。

在我的例子中,添加了包含数千个方法的GlassVoice-xe17.apk,使我的应用触及了臭名昭著的"64K方法"Android上限。如果你不知道这个可怕的限制是什么,只要想想"MS-DOS中的640K",由Android (Dalvik VM)重新发明。

首先,我试图打开ProGuard,为了缩小我的应用程序,通过删除所有未使用的方法:问题是,这是一个噩梦配置,经过几个小时的失败尝试,我仍然有意想不到的类丢失和神秘的错误。

所以我转向Dex加载,如下所述:https://github.com/mmin18/Dex65536。问题是GlassVoice.apk包含了所有的com.google.common包,我也通过Guava使用这些包。在Dex65536解决方案中,类加载器首先从外部APK加载类(很好的hack,你不能转过来),因此它不能工作。

我最终编写了一个"类预加载器",在添加额外的Dex ClassLoader之前调用。如果你对代码感兴趣,请给我写信(但它远非最佳)。

那是艰难和丑陋的!我希望谷歌眼镜开发团队能尽快解决声音问题,用一个简洁的解决方案——而不是像这个:-)

仍然适用于我在XE17上使用这里描述的方法:Glass语音命令最接近给定列表的匹配,也许您使用null

调用初始setVoiceConfig。

或者,如果你可以退回到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

最新更新