Running Android Speech Recognition as Service: wil

2019-05-21 18:47发布

问题:

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;
        }
    }