Android语音识别(SpeechRecognizer)中的onReadyForSpeech()永远不会被调用

时间:2017-02-01 19:06:34

标签: android speech-recognition

这是我的代码:

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_create_route);

    SetupButton();

}

private void SetupButton()
{
    Button createNewMessage = (Button) findViewById(R.id.button);

    createNewMessage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ListenForNewMessage();
        }
    });
}

private void ListenForNewMessage()
{
    final SpeechRecognizer newDeliverySpeech = SpeechRecognizer.createSpeechRecognizer(this);
    RecognitionListener newDeliveryRecognitionListener = new RecognitionListener() {
        @Override
        public void onReadyForSpeech(Bundle params) {
            Log.d("SpeechListening","onReadyForSpeech");
        }
        @Override
        public void onBeginningOfSpeech() {
            Log.d("SpeechListening","onBeginningOfSpeech");
        }

        @Override
        public void onRmsChanged(float rmsdB) {
            //do nothing
        }

        @Override
        public void onBufferReceived(byte[] buffer) {
            //do nothing
        }

        @Override
        public void onEndOfSpeech() {
            Log.d("SpeechListening","onEndOfSpeech");
        }

        @Override
        public void onError(int error) {
            //do nothing
        }

        @Override
        public void onResults(Bundle results) {
            ArrayList<String> userMessage;
            userMessage = results.getStringArrayList(RESULTS_RECOGNITION);
            PushNewDelivery(userMessage);
        }

        @Override
        public void onPartialResults(Bundle partialResults) {
            //do nothing
        }

        @Override
        public void onEvent(int eventType, Bundle params) {
            //do nothing
        }
    };
    newDeliverySpeech.setRecognitionListener(newDeliveryRecognitionListener);
    if (newDeliverySpeech.isRecognitionAvailable(getApplicationContext()))
    {
        Log.d("SpeechListening","started listening hopefully");
        newDeliverySpeech.startListening(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH));
    }
}

}

问题是,只记录了开始聆听希望RecognitionListener从未调用onReadyForSpeech()或其任何方法。

细节 细节 细节 细节 有人可以告诉我这里我做错了吗?

1 个答案:

答案 0 :(得分:1)

您基本上是在创建一个新的SpeechRecognizer对象,并在每次单击按钮时注册一个新的侦听器。最重要的是,您使用当前的Activity Context创建SpeechRecognizer,但在调用时实际上是在使用Application上下文:isRecognitionAvailable();

尝试将SpeechRecognizer创建为成员对象,并在调用onCreate()时注册侦听器。还要尽量避免使用Application上下文来避免内存泄漏。

以下是您应该如何操作的示例。

private SpeechRecognizer mDeliverySpeech;
private Intent mSpeechIntent;
private boolean mListening = false;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_create_route);

    SetupButton();
    SetupSpeechRecognizer();

    mSpeechIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);

    mSpeechIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "en");
    mSpeechIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
    mSpeechIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    mSpeechIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3);
}

private void SetupButton()
{
    Button createNewMessage = (Button) findViewById(R.id.button);

    createNewMessage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ListenForNewMessage();
        }
    });
}

private void SetupSpeechRecognizer() 
{
    mDeliverySpeech = SpeechRecognizer.createSpeechRecognizer(this);

     RecognitionListener newDeliveryRecognitionListener = new RecognitionListener() {
        @Override
        public void onReadyForSpeech(Bundle params) {
            Log.d("SpeechListening","onReadyForSpeech");
        }
        @Override
        public void onBeginningOfSpeech() {
            Log.d("SpeechListening","onBeginningOfSpeech");
        }

        @Override
        public void onRmsChanged(float rmsdB) {
            //do nothing
        }

        @Override
        public void onBufferReceived(byte[] buffer) {
            //do nothing
        }

        @Override
        public void onEndOfSpeech() {
            Log.d("SpeechListening","onEndOfSpeech");
        }

        @Override
        public void onError(int error) {
            //do nothing
        }

        @Override
        public void onResults(Bundle results) {
            ArrayList<String> userMessage;
            userMessage = results.getStringArrayList(RESULTS_RECOGNITION);
            PushNewDelivery(userMessage);
        }

        @Override
        public void onPartialResults(Bundle partialResults) {
            //do nothing
        }

        @Override
        public void onEvent(int eventType, Bundle params) {
            //do nothing
        }
    };

    mDeliverySpeech.setRecognitionListener(newDeliveryRecognitionListener);
}

private void ListenForNewMessage()
{   
    if (mDeliverySpeech.isRecognitionAvailable(this) && !mListening)
    {
        Log.d("SpeechListening","started listening hopefully");

        mListening = true;

        mDeliverySpeech.startListening(mSpeechIntent);

        new CountDownTimer(5000, 5000) {
             public void onTick(long millisUntilFinished) {}

             public void onFinish() {
                 mDeliverySpeech.stopListening();
                 mListening = false;
             }
          }.start();
    }
}

在使用侦听器时,不要忘记正确处理活动生命周期,以避免内存泄漏。