Voice Recognition stops listening after a few seconds

前端 未结 5 1276
执笔经年
执笔经年 2020-11-29 01:20

I tried a lot but can´t find it out, so I hope you can help me.

I am trying to build my own voice recognition app, which doesn´t show up the dialog.

I alread

5条回答
  •  攒了一身酷
    2020-11-29 01:59

    I have made a Service that bears an Audio to Speech Recognizer that simulates being continuous by restarting itself everytime there is an error or result. As you can see, my service listens to a Broadcast receiver in order to start/stop continuous ASR (it is battery expensive so I recommend you run this continuous ASR service only while your relevant UI is in the foreground). The results of the ASR are also broadcasted to the rest of the app. You can ignore the broadcasting, the service and the Recognizer Listener are the main idea. DONT forget the INTERNET permission and the manifest, and the service declaration:

    
    

    SpeechRecognitionService:

        /**
         * Created by Josh on 22/07/15.
         *  This service bears an Audio to Speech recognizer (ASR), once this service is started,
         *  it listens a broadcast called "asrService".
         *  the Service starts ASR when it receives a "START-ASR" value inside the "message" parameter of its broadcast receiver
         *  the Service stopss ASR when it receives a  "STOP-ASR" value inside the "message" parameter of its broadcast receiver
         Example:
         Intent intent = new Intent("asrService");
         intent.putExtra("message", "STOP-ASR");
         LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
         Once the ASR Listener that this service bears is running, it will broadcast the results is gets.
         To catch ASR results, implement a Broadcast receiver that listens to app.asrResult="ASRresult", for example:
    
         private BroadcastReceiver ASRReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String message = intent.getStringExtra("message");
                if(message!=null) {
                    app.logwhite("ASR says: "+message);
                }
            }
        };
         LocalBroadcastManager.getInstance(this).registerReceiver(ASRReceiver, new IntentFilter(app.asrResult));
    
         Unregister the broadcast receiver likewise:
         LocalBroadcastManager.getInstance(this).unregisterReceiver(ASRReceiver);
         */
    
        public class speechRecognitionService extends Service {
    
            private static speechRecognitionListenerJosh speechReconListener;
            private static SpeechRecognizer mSpeechRecognizer=null;
            private static Intent mSpeechRecognizerIntent;
            private static boolean mIslistening=false;
    
    
            //======== BROADCAST RECEIVERS
            // handler for received Intents for the "my-event" event
            private BroadcastReceiver startASRReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    String message = intent.getStringExtra("message");
                    if(message.equals("START-ASR")) {
                        if (mIslistening == false) {
    
    
                            if (mSpeechRecognizer != null) {
                                mSpeechRecognizer.destroy();
                                mSpeechRecognizer = null;
                            }
                            app.logy("==BROADCAST Rx: START_ASR");
    
                            mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
                            mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "en-US");
                            mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
                            //mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
                            //mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE ,   this.getPackageName());
                            mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, 5000);
                            mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS, 5000);
                            //mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true);
                            //mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3);
    
                            mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(getApplicationContext());
                            speechReconListener = new speechRecognitionListenerJosh();
                            mSpeechRecognizer.setRecognitionListener(speechReconListener);
    
                            mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
                        } else {
                            app.logy("==BROADCAST Rx: STOP_ASR");
                            mSpeechRecognizer.stopListening();
                            mSpeechRecognizer.destroy();
                            speechReconListener = null;
                        }
                    }
    
                    if(message.equals("STOP-ASR")){
                        app.logy("==BROADCAST Rx: STOP_ASR");
                        mSpeechRecognizer.stopListening();
                        mSpeechRecognizer.destroy();
                        speechReconListener = null;
                    }
                }
            };
    
    
            @Override
            public void onCreate() {
                super.onCreate();
    
                mSpeechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
                mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "en-US");
                mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL  ,   RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
                //mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
                mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE ,   this.getPackageName());
                mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS, 4000);
                mSpeechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3);
                mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
                speechReconListener = new speechRecognitionListenerJosh();
                mSpeechRecognizer.setRecognitionListener(speechReconListener);
    
                LocalBroadcastManager.getInstance(this).registerReceiver(startASRReceiver, new IntentFilter("asrService"));
                app.toastlog("==ASR Service - CREATED");
            }
    
            @Override
            public void onDestroy() {
                super.onDestroy();
                LocalBroadcastManager.getInstance(this).unregisterReceiver(startASRReceiver);
    
                if (mSpeechRecognizer != null){
                    mSpeechRecognizer.destroy();
                    mSpeechRecognizer=null;
                }
                app.toastlog("==ASR Service - DESTROYED");
            }
    
            @Override
            public IBinder onBind(Intent intent) {
                return null;
            }
    
            @Override //rather not use, runs before onStart
            public int onStartCommand(Intent intent, int flags, int startId) {
                return super.onStartCommand(intent, flags, startId);
            }
    
            @Override
            public void onStart(Intent intent, int startId) {
                super.onStart(intent, startId);
                app.toastlog("==ASRservice - onStart");
            }
    
    
    
            private class speechRecognitionListenerJosh  implements RecognitionListener {
    
                @Override
                public void onBeginningOfSpeech() {
                    mIslistening=true;
                    app.loge("=ASRListener - onBeginingOfSpeech");
                }
    
                @Override
                public void onBufferReceived(byte[] buffer){
    
                }
    
                @Override
                public void onEndOfSpeech(){
                    app.loge("=ASRListener - onEndOfSpeech");
                }
    
                @Override
                public void onError(int error) {
                    mIslistening=false;
                    String code= Integer.toString(error);
    
                    if(error==SpeechRecognizer.ERROR_CLIENT){ // 5
                        code="ERROR_CLIENT";
                        mIslistening=false;
                        mSpeechRecognizer.destroy();
                        Intent intent = new Intent("asrService");
                        intent.putExtra("message", "START-ASR");
                        LocalBroadcastManager.getInstance(app.appContext).sendBroadcast(intent);
                    }
    
                    if(error==SpeechRecognizer.ERROR_SPEECH_TIMEOUT){ // 6
                        code="SPEECH_TIMEOUT";
                        mSpeechRecognizer.stopListening();
                        mIslistening=false;
                        Intent intent = new Intent("asrService");
                        intent.putExtra("message", "START-ASR");
                        LocalBroadcastManager.getInstance(app.appContext).sendBroadcast(intent);
                        //Usualy bounces back to ERROR_CLIENT.
                    }
                    if(error==SpeechRecognizer.ERROR_NO_MATCH){ // 7
                        code="ERROR_NO_MATCH";
                        mIslistening=false;
                        Intent intent = new Intent("asrService");
                        intent.putExtra("message", "START-ASR");
                        LocalBroadcastManager.getInstance(app.appContext).sendBroadcast(intent);
                        //Usually bounces back to ERROR_CLIENT.
                    }
    
                    app.loge("=ASRListener - ASR Error: "+code);
                    /*
                    // 1 = NETWORK_TIMEOUT
                    // 2 = ERROR_NETWORK
                    // 3 = ERROR_AUDIO
                    // 4 = ERROR_SERVER
                    // 5 = ERROR_CLIENT
                    // 8 = ERROR_RECOGNIZER_BUSY
                    // 9 = ERROR_INSUFFICIENT_PERMISSIONS
                    */
    
                }
    
                @Override
                public void onEvent(int eventType, Bundle params){
    
                }
    
                @Override //Somehow doesn't trigger upon partial results
                public void onPartialResults(Bundle partialResults){
                    ArrayList results=partialResults.getStringArrayList("EXTRA_PARTIAL_RECOGNITION");
                    if(results!=null) {
                        if (results.size() > 0) {
                            app.logwhite("=== ASR Partial Results: " + results);
                        }
                    }
                }
    
                @Override
                public void onReadyForSpeech(Bundle params){
                    app.loge("=ASRListener - onReadyForSpeech, LISTENING  (((( ");
                }
    
                @Override
                public void onResults(Bundle resultBundle){
                    app.loge("=ASRListener - onResults");
                    ArrayList result = resultBundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
                    if(result!=null) {  //when speaking timeout happen, results is null
    
                        // matches are the return values of speech recognition engine
    
                        if (result.size() > 0) {
                            app.logwhite("=== ASR Results:");
                            app.logwhite(result.get(0));
                            //BC name, message
                            app.broadcast(app.asrResult,result.get(0)); //The result is broadcast to the entire app
                        }
    
                    }
    
                    mIslistening=false;
                    Intent intent = new Intent("asrService");
                    intent.putExtra("message", "START-ASR");
                    LocalBroadcastManager.getInstance(app.appContext).sendBroadcast(intent);
                }
    
                @Override
                public void onRmsChanged(float rmsdB){
                    //VOLUME VUmeter!!!!
                }
            }
        }
    

提交回复
热议问题