How do I use Android SpeechRecognizer as a service

2019-03-28 16:33发布

问题:

I am trying to run Android voice recognition as a service. I can verify that the onCreate() and onStart() methods of the service are called, but no callbacks to the speech recognition methods are called, despite the fact that I have set up the SpeechRecognizer object correctly. The speech recognition seems to work when it is done in an activity instead of a service. How do I make it work as a service? Is this a manifest issue?

package net.viralpatel.android.speechtotextdemo;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.util.Log;
import android.widget.Toast;

public class MyService extends Service implements RecognitionListener {
    private SpeechRecognizer speechRecognizer;
    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }
    @Override
    public void onCreate() {
        Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
        Log.d("tag", "onCreate");
        speechRecognizer = SpeechRecognizer.createSpeechRecognizer(getApplicationContext());
        speechRecognizer.setRecognitionListener(this);

        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);

        speechRecognizer.startListening(intent); 
    }

    @Override
    public void onDestroy() {
        Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
        Log.d("tag", "onDestroy");
    }

    @Override
    public void onStart(Intent intent, int startid) {
        Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
        Log.d("tag", "onStart");
    }

    @Override
     public void onBeginningOfSpeech() {
      Log.d("Speech", "onBeginningOfSpeech");
     }

     @Override
     public void onBufferReceived(byte[] buffer) {
      Log.d("Speech", "onBufferReceived");
     }

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

     @Override
     public void onError(int error) {
      Log.d("Speech", "onError");
     }

     @Override
     public void onEvent(int eventType, Bundle params) {
      Log.d("Speech", "onEvent");
     }

     @Override
     public void onPartialResults(Bundle partialResults) {
      Log.d("Speech", "onPartialResults");
     }

     @Override
     public void onReadyForSpeech(Bundle params) {
      Log.d("Speech", "onReadyForSpeech");
     }

     @Override
     public void onResults(Bundle results) {
      Log.d("Speech", "onResults");
      ArrayList strlist = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
      for (int i = 0; i < strlist.size();i++ ) {
       Log.d("Speech", "result=" + strlist.get(i));
      }
      BufferedWriter out;
    try {
        out = new BufferedWriter(new FileWriter("mnt/sdcard/results.txt"));
//        out.write(processor.execute(strlist.get(0).toString()));
          out.write("hello world"); 
    } catch (IOException e) {
        Log.e("Speech",e.toString());
    }
     }

     @Override
     public void onRmsChanged(float rmsdB) {
      Log.d("Speech", "onRmsChanged");
     }
}

回答1:

There are 2 things that I think you need to clarify and may provide you as a workaround.

  1. Have declared the service in the manifest properly? I believe this is something already addressed.

  2. Speech recognition may not start "onCreate" of the service. I had done similar implementation but it didn't work. You can try placing the startListening(intent) in some other method and call it explicitly. This worked for me.

Let me know if it helps.



回答2:

you can do this:

public class OpenMicService extends Service implements RecognitionListener{

    private static final int VOICE_RECOGNITION_REQUEST_CODE = 1234;
    private SpeechRecognizer speechRecognizer;

    @Nullable
    @Override

    public IBinder onBind(Intent intent) {


        return null;
    }

    @Override
    public int onStartCommand(Intent intent,int flags,int startId) {

        Toast.makeText(this,"start Service.",Toast.LENGTH_SHORT).show();

        speechRecognizer = SpeechRecognizer.createSpeechRecognizer(getApplicationContext());
        speechRecognizer.setRecognitionListener(this);

        Intent voice = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        voice.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getClass()
                .getPackage().getName());
        voice.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        voice.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 10);

        speechRecognizer.startListening(voice);

        return START_REDELIVER_INTENT;

    }

    @Override
    public void onDestroy() {

        super.onDestroy();
    }


    @Override
    public void onReadyForSpeech(Bundle bundle) {

    }

    @Override
    public void onBeginningOfSpeech() {

    }

    @Override
    public void onRmsChanged(float v) {

    }

    @Override
    public void onBufferReceived(byte[] bytes) {

    }

    @Override
    public void onEndOfSpeech() {

    }

    @Override
    public void onError(int i) {

    }

    @Override
    public void onResults(Bundle results) {

        String wordStr = null;
        String[] words = null;
        String firstWord = null;
        String secondWord = null;

        ArrayList<String> matches = results
                .getStringArrayList(speechRecognizer.RESULTS_RECOGNITION);
        wordStr = matches.get(0);
        words = wordStr.split(" ");
        firstWord = words[0];
        secondWord = words[1];

        if (firstWord.equals("open")) {
            PackageManager packageManager = getPackageManager();
            List<PackageInfo> packs = packageManager
                    .getInstalledPackages(0);
            int size = packs.size();
            boolean uninstallApp = false;
            boolean exceptFlg = false;
            for (int v = 0; v < size; v++) {
                PackageInfo p = packs.get(v);
                String tmpAppName = p.applicationInfo.loadLabel(
                        packageManager).toString();
                String pname = p.packageName;
                //URL urlAddress = urlAddress.toLowerCase();
                tmpAppName = tmpAppName.toLowerCase();
                if (tmpAppName.trim().toLowerCase().equals(secondWord.trim().toLowerCase())) {
                    PackageManager pm = this.getPackageManager();
                    Intent appStartIntent = pm.getLaunchIntentForPackage(pname);
                    if (null != appStartIntent) {
                        try {
                            this.startActivity(appStartIntent);
                        } catch (Exception e) {
                        }
                    }
                }
            }
        } // end of open app code
    }

    @Override
    public void onPartialResults(Bundle bundle) {

    }

    @Override
    public void onEvent(int i,Bundle bundle) {

    }
}