2

I'm using the solution here: Android Speech Recognition as a service on Android 4.1 & 4.2 The code below gets to the onStartCommand() method, however the speech recogntion never seems to kick off, as evidenced by the fact that the onReadyForSpeech() method is never called.

UPDATE: So I added and that allowed the onReadyForSpeech() to be called , BUT onError() is called with error code: 6 after the onReadyForSpeech() method is complete (this goes into a continuous loop because the start listening code is started again after onError() is called). Like Hoan Nguyen states below, error code 6 is ERROR_SPEECH_TIMEOUT BUT I never see a speech recognition dialog come up so I know to start speaking. I also tried to start speaking immediately after kicking off this code without that dialog coming and still get error code 6, what am I doing wrong here?

UPDATE (9-06-13): Like Hoan stated, there is no dialog that comes up. You just start talking as soon as listening is called. But I ran into another issue where trying to restart the listener after every onResult() is called...That issue and the complete code for this can be found here: Android Speech Speech Recognition: Repeated Calling of SpeechRecognizer.startListening() fails on JB 4.1.2

My activity code that calls the service:

startService(new Intent(VoiceRecognition.this, VoiceRecogService.class));

My service:

public class VoiceRecogService extends Service
    {
        protected AudioManager mAudioManager; 
        protected SpeechRecognizer mSpeechRecognizer;
        protected Intent mSpeechRecognizerIntent;
        protected final Messenger mServerMessenger = new Messenger(new IncomingHandler(this));

        protected boolean mIsListening;
        protected volatile boolean mIsCountDownOn;

        static final int MSG_RECOGNIZER_START_LISTENING = 1;
        static final int MSG_RECOGNIZER_CANCEL = 2;

        private int mBindFlag;
        private Messenger mServiceMessenger;

        @Override
        public void onCreate()
        {
            super.onCreate();
            mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 
            mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
            mSpeechRecognizer.setRecognitionListener(new SpeechRecognitionListener());
            mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
            mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                                             RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
            mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
                                             this.getPackageName());

            //mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
        }

        protected static class IncomingHandler extends Handler
        {
            private WeakReference<VoiceRecogService> mtarget;

            IncomingHandler(VoiceRecogService target)
            {
                mtarget = new WeakReference<VoiceRecogService>(target);
            }


            @Override
            public void handleMessage(Message msg)
            {
                final VoiceRecogService target = mtarget.get();

                switch (msg.what)
                {
                    case MSG_RECOGNIZER_START_LISTENING:

                        if (Build.VERSION.SDK_INT >= 16);//Build.VERSION_CODES.JELLY_BEAN)
                        {
                            // turn off beep sound  
                            target.mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, true);
                        }
                         if (!target.mIsListening)
                         {
                             target.mSpeechRecognizer.startListening(target.mSpeechRecognizerIntent);
                             target.mIsListening = true;
                            //Log.d(TAG, "message start listening"); //$NON-NLS-1$
                         }
                         break;

                     case MSG_RECOGNIZER_CANCEL:
                          target.mSpeechRecognizer.cancel();
                          target.mIsListening = false;
                          //Log.d(TAG, "message canceled recognizer"); //$NON-NLS-1$
                          break;
                 }
           } 
        } 

        // Count down timer for Jelly Bean work around
        protected CountDownTimer mNoSpeechCountDown = new CountDownTimer(5000, 5000)
        {

            @Override
            public void onTick(long millisUntilFinished)
            {
                // TODO Auto-generated method stub

            }

            @Override
            public void onFinish()
            {
                mIsCountDownOn = false;
                Message message = Message.obtain(null, MSG_RECOGNIZER_CANCEL);
                try
                {
                    mServerMessenger.send(message);
                    message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
                    mServerMessenger.send(message);
                }
                catch (RemoteException e)
                {

                }
            }
        };

        @Override
        public int onStartCommand (Intent intent, int flags, int startId) 
        {
            //mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
            try
            {
                Message msg = new Message();
                msg.what = MSG_RECOGNIZER_START_LISTENING; 
                mServerMessenger.send(msg);
            }
            catch (RemoteException e)
            {

            }
            return  START_NOT_STICKY;
        }

        @Override
        public void onDestroy()
        {
            super.onDestroy();

            if (mIsCountDownOn)
            {
                mNoSpeechCountDown.cancel();
            }
            if (mSpeechRecognizer != null)
            {
                mSpeechRecognizer.destroy();
            }
        }

        protected class SpeechRecognitionListener implements RecognitionListener
        {

            @Override
            public void onBeginningOfSpeech()
            {
                // speech input will be processed, so there is no need for count down anymore
                if (mIsCountDownOn)
                {
                    mIsCountDownOn = false;
                    mNoSpeechCountDown.cancel();
                }               
                //Log.d(TAG, "onBeginingOfSpeech"); //$NON-NLS-1$
            }

            @Override
            public void onBufferReceived(byte[] buffer)
            {
                String sTest = "";
            }

            @Override
            public void onEndOfSpeech()
            {
                Log.d("TESTING: SPEECH SERVICE", "onEndOfSpeech"); //$NON-NLS-1$
             }

            @Override
            public void onError(int error)
            {
                if (mIsCountDownOn)
                {
                    mIsCountDownOn = false;
                    mNoSpeechCountDown.cancel();
                }
                 mIsListening = false;
                 Message message = Message.obtain(null, MSG_RECOGNIZER_START_LISTENING);
                 try
                 {
                        mServerMessenger.send(message);
                 }
                 catch (RemoteException e)
                 {

                 }
                //Log.d(TAG, "error = " + error); //$NON-NLS-1$
            }

            @Override
            public void onEvent(int eventType, Bundle params)
            {

            }

            @Override
            public void onPartialResults(Bundle partialResults)
            {

            }

            @Override
            public void onReadyForSpeech(Bundle params)
            {
                if (Build.VERSION.SDK_INT >= 16);//Build.VERSION_CODES.JELLY_BEAN)
                {
                    mIsCountDownOn = true;
                    mNoSpeechCountDown.start();
                    mAudioManager.setStreamMute(AudioManager.STREAM_SYSTEM, false);
                }
                Log.d("TESTING: SPEECH SERVICE", "onReadyForSpeech"); //$NON-NLS-1$
            }

            @Override
            public void onResults(Bundle results)
            {
                //Log.d(TAG, "onResults"); //$NON-NLS-1$

            }

            @Override
            public void onRmsChanged(float rmsdB)
            {

            }



        }

        @Override
        public IBinder onBind(Intent arg0) {
            // TODO Auto-generated method stub
            return null;
        }
    }
Community
  • 1
  • 1
Mike6679
  • 5,547
  • 19
  • 63
  • 108
  • Comment out Log.d(TAG, "message start listening"); in the handleMessage(Message msg) method to see if it was called. – Hoan Nguyen Sep 04 '13 at 05:02
  • 1
    Yes handleMessage() is called , repeatedly actually, is that correct? – Mike6679 Sep 04 '13 at 05:09
  • If your device is JB then it seems that the countdown timer is working, that means onReadyForSpeech is called. – Hoan Nguyen Sep 04 '13 at 05:16
  • ok I see that onError() is called which starts everything over again which is why onReadyForSpeech is never called & why handleMessage() is called repeatedly. The error code is 9...any idea what the error could be – Mike6679 Sep 04 '13 at 05:28
  • 2
  • Ok, great, now onReadyForSpeech is called but now onError() is called again with error code 6. – Mike6679 Sep 04 '13 at 05:44
  • That is because you do not speak in the allotted time. If your device OS is not JB you have to speak within certain amount of time otherwise you get ERROR_SPEECH_TIMEOUT – Hoan Nguyen Sep 04 '13 at 05:50
  • The device I'm testing on IS JB though. – Mike6679 Sep 04 '13 at 16:22
  • There will be no dialog, just start speaking as soon as onReadyForSpeech is logged. – Hoan Nguyen Sep 05 '13 at 03:39
  • Hoan: Thanks for the help. Have you ever see the case whereby calling startListening() after onResult() will fail after a random number of calls (usually 3- 5 times) ?. See my update in the question above for details. – Mike6679 Sep 06 '13 at 20:08

0 Answers0