3

AndroidでSpeechRecognizerとRecognizerIntentを使用して、音声認識を実装しています。私の目的は、音声認識機能が画面に結果を表示した後、音声の聞き取りを再開することです。そのために、次のコードを使用しています。

問題は、1回目は正常に実行されて結果が表示されますが、2回目(onResultsメソッドから呼び出される)のリッスンを開始した後、何らかの理由で話されている内容が聞こえないことです。次に、ERROR_SPEECH_TIMEOUTエラーが発生します。これは、音声入力がなかったことを意味します。Logcatでは、onReadyForSpeech()に入るのを見ることができますが、どういうわけか、私が言っていることが聞こえません。

なぜこれが起こるのか誰かが知っていますか?結果を返した後も聞き続けますか?startListeningを再度明示的に呼び出すのは正しいですか?

public class VR extends Activity implements RecognitionListener {


    private static final int VOICE_RECOGNITION_REQUEST_CODE = 1234;
    private TextView vrtext;
    private SpeechRecognizer speech = null;
    private Intent intent;
    private String TAG = "VR";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.vr);

        vrtext = (TextView) findViewById(R.id.vrtext);  

    }

    @Override
    public void onResume()
    {
        listen();
        super.onResume();
    }

    private void listen()
    {
        speech = SpeechRecognizer.createSpeechRecognizer(this);
        speech.setRecognitionListener(this);
        intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "en");
        intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
        intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3);

        speech.startListening(intent);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // TODO Auto-generated method stub

        if(speech != null)
        {
            speech.destroy();
            Log.i(TAG,"destroy");
        }

    }

    public void onBeginningOfSpeech() {
        // TODO Auto-generated method stub
        Log.i(TAG, "onbeginningofspeech");
    }

    public void onBufferReceived(byte[] arg0) {
        // TODO Auto-generated method stub
        //Log.i(TAG, "onbufferreceived");
    }

    public void onEndOfSpeech() {
        // TODO Auto-generated method stub
        Log.i(TAG, "onendofspeech");
    }

    public void onError(int arg0) {
        // TODO Auto-generated method stub
        Log.i(TAG, "error code: " + arg0);
    }

    public void onEvent(int arg0, Bundle arg1) {
        // TODO Auto-generated method stub
        Log.i(TAG, "onevent");
    }

    public void onPartialResults(Bundle arg0) {
        // TODO Auto-generated method stub
        Log.i(TAG, "onpartialresults");
    }

    public void onReadyForSpeech(Bundle arg0) {
        // TODO Auto-generated method stub
        Log.i(TAG, "onreadyforspeech");
    }

    public void onResults(Bundle arg0) {
        // TODO Auto-generated method stub
        Log.i(TAG, "onresults");
        ArrayList<String> matches = arg0.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
        String s = "";
        for (String result:matches)
            s += result + "\n";

        vrtext.setText(s);

        speech.startListening(intent);

    }

    public void onRmsChanged(float arg0) {
        // TODO Auto-generated method stub
        //Log.i(TAG, "onrmschanged");
    }

}
4

2 に答える 2

2

「結果が返った後も聴き続けますか?」いいえ

「startListeningを再度明示的に呼び出すのは正しいですか?」はい。

また、認識を継続的に実行したい場合は、次のstartListeningようなエラーが発生した場合に再度呼び出す必要があります。

@Override
public void onError(int errorCode)
{
    if ((errorCode == SpeechRecognizer.ERROR_NO_MATCH)
            || (errorCode == SpeechRecognizer.ERROR_SPEECH_TIMEOUT))
    {
        Log.d(TAG, "didn't recognize anything");
        // keep going
        recognizeSpeechDirectly();
    }
    else
    {
        Log.d(TAG,
                "FAILED "
                        + SpeechRecognitionUtil
                                .diagnoseErrorCode(errorCode));
    }
}

ここでSpeechRecognizer特定の話し言葉を検出するために使用するための私のコードをチェックしてください。

于 2012-06-27T09:55:26.877 に答える
1

SpeechRecognizerアクティビティ内で単一のオブジェクトを使用するようにしてください。迅速で汚い方法は、それを静的にすることです。

private static SpeechRecognizer speech = null;

メソッドを変更listen()して、音声オブジェクトのnullをチェックします。

private void listen()
{
    if (speech == null) {
        speech = SpeechRecognizer.createSpeechRecognizer(this);
        speech.setRecognitionListener(this);
    }
    intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "en");
    intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
    intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3);

    speech.startListening(intent);
}

でlistenメソッドを呼び出しonResults()ますonError()

public void onResults(Bundle arg0) {
    // TODO Auto-generated method stub
    Log.i(TAG, "onresults");
    ArrayList<String> matches = arg0.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
    String s = "";
    for (String result:matches)
        s += result + "\n";

    vrtext.setText(s);

    //speech.startListening(intent);
    listen();

}

public void onError(int arg0) {
    // TODO Auto-generated method stub
    Log.i(TAG, "error code: " + arg0);
    listen();
}

そして最後に、で必要なクリーニングを行うことを忘れないでくださいonDestroy()

@Override
public void onDestroy() {
    super.onDestroy();
    speech.destroy();
}
于 2014-08-08T10:31:23.820 に答える