9

谷歌语音搜索从您通过 startActivityForResult() 调用它的那一刻起,直到它的对话框显示,准备好接受您的演讲,都会有很大的延迟。

这要求用户在说话之前总是看着屏幕,等待对话框显示出来。

因此,我正在考虑通过实现 RecognitionListener 并在 onReadyForSpeech() 中发出 DTMF 音来生成可听信号而不是对话框,如下面的片段:

  @Override
  public void onReadyForSpeech(Bundle params) {
    Log.d(LCTAG, "Called when the endpointer is ready for the user to start speaking.");
    mToneGenerator.startTone(ToneGenerator.TONE_DTMF_1);
    try {
      Thread.sleep(50);
    } catch (InterruptedException e) {
      Log.e(LCTAG, "InterruptedException while in Thread.sleep(50).");        
      e.printStackTrace();
    } // SystemClock.sleep(50);
    mToneGenerator.stopTone();
  }

音调听起来很美,但是......它也被麦克风“听到”,到达语音识别服务并总是产生识别错误ERROR_NO_MATCH

有没有办法解决这个问题?

4

3 回答 3

5

这是一个随机的想法,它很可能行不通。

AudioManager.setMicrophoneMute您可以尝试在播放音调时禁用麦克风(可能通过)吗?

于 2011-04-20T17:59:00.307 回答
1

这是适用于我的代码,放入 RecognitionListener 的 onReadyForSpeech() 回调中。

private void playSpeechReadyTone(){
    audioManager.setMicrophoneMute(true);
    MediaPlayer mediaPlayer = MediaPlayer.create(JarvisService.this, R.raw.doublebeep);
    mediaPlayer.setOnCompletionListener(new OnCompletionListener() {

        @Override
        public void onCompletion(MediaPlayer arg0) {
            audioManager.setMicrophoneMute(false);
        }
    });
    mediaPlayer.start();    
}
于 2011-10-06T21:01:57.370 回答
0

恐怕没有一种简单干净的方法可以做到这一点。正如 srf 指定的那样,您不应该依赖 AudioManager.setMicrophoneMute(boolean),因此,AFAIK,可能的情况是:

  1. 在调用 SpeechRecognizer.startListening(intent) 之前播放音频文件:

    final MediaPlayer mediaPlayer = MediaPlayer.create(JarvisService.this, R.raw.doublebeep);
    mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
    
         @Override
        public void onCompletion(MediaPlayer player) {
            player.release();
            // Safety start Speech Recognizer
            mSpeechRecognizer.startListening(getSpeechRecognizerIntent());
        }
    });
    mediaPlayer.start();
    

但是,这个解决方案有一个问题......如果在 RecognitionListener.onReadyForSpeech 被调用之前可能会收到一个 RecognitionListener.onError(int error) 并且在这种情况下,您仍然每次都在播放哔声(例如,这种情况会发生,如果您未连接到 Internet 并且语音识别已配置为在线工作)!此外,您应该管理在音频(双哔声)播放期间取消语音识别过程的情况。

  1. 在 onReadyForSpeech 回调中播放音频(阅读原始问题),但使用具有适当值的 RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS。就我而言,我的哔声真的很短(最多 1 秒),我将 RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS 设置为 4/5 秒。

另请注意,正如谷歌文档所说:

另请注意,某些值可能会导致不希望或意外的结果 - 请谨慎使用!此外,根据识别器的实现,这些值可能无效。

于 2013-07-19T09:36:45.683 回答