Android VoiceRecognition onActivityResult

#android #voice-recognition #activity-lifecycle

#Android #распознавание голоса #активность-жизненный цикл

Вопрос:

мы пытаемся реализовать простой тест, который должен управляться VoiceRecognition. Мы должны выполнить один вопрос и один ответ. В QuestionActivity вопрос считывается TextToSpeech, а затем пользователь может ответить на действие распознавания голоса. Затем AnswerActivity запускается startActivityForResult(…), который также использует распознавание голоса, чтобы пользователь мог вернуться к следующему вопросу. Однако, если пользователь вернется к своему второму вопросу, распознаватель голоса не будет работать из-за неизвестной ошибки. Смотрите пример кода ниже:

 public class QuestionActivity extends Activity implements OnClickListener, OnInitListener, OnUtteranceCompletedListener {

private static final int VOICE_RECOGNITION_REQUEST_CODE = 1234;

private TxtToSpeech toSpeech = null;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    toSpeech = new TxtToSpeech(this);
    setContentView(R.layout.main);

    // Get display items for later interaction
    Button speakButton = (Button) findViewById(R.id.btn_speak);

    // Check to see if a recognition activity is present
    PackageManager pm = getPackageManager();
    List<ResolveInfo> activities = pm.queryIntentActivities(
            new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
    if (activities.size() != 0) {
        speakButton.setOnClickListener(this);
    } else {
        speakButton.setEnabled(false);
        speakButton.setText("Recognizer not present");
    }
}

public void onClick(View v) {
    if (v.getId() == R.id.btn_speak) {
        startVoiceRecognitionActivity();
    }
}

private void startVoiceRecognitionActivity() {
    Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
            RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speech recognition demo");
    intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
    startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == VOICE_RECOGNITION_REQUEST_CODE amp;amp; resultCode == RESULT_OK) {
        //---Code to restart
        //Without this code the recognizer wont work!
        Intent i = getIntent();
        finish();
        startActivity(i);
        //-----------------

        Intent intent = new Intent(this, SubActivity.class);
        startActivityForResult(intent , 2222);
    }
    else if( requestCode == 2222 )
    {
        saySomething();
    }

    super.onActivityResult(requestCode, resultCode, data);
}

void saySomething()
{
    toSpeech.playVoice(new String[] {"My Question"}, true); //true == start Recognition afterwards
}
@Override
public void onInit(int status) {
    toSpeech.mTts.setLanguage(Locale.US);
    toSpeech.mTts.setOnUtteranceCompletedListener(this);
    saySomething();
}

@Override
public void onUtteranceCompleted(String utteranceId) {
    startVoiceRecognitionActivity();
}
  

открытый класс AnswerActivity расширяет действие, реализует OnInitListener, OnUtteranceCompletedListener{

 public final static int VOICE_RECOGNITION_REQUEST_CODE = 4321;
private TxtToSpeech toSpeech = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    toSpeech = new TxtToSpeech(this);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        setResult(RESULT_OK);
        finish();

    super.onActivityResult(requestCode, resultCode, data);
}

@Override
public void onUtteranceCompleted(String utteranceId) {
    Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
            RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speech recognition demo");
    startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
}

@Override
public void onInit(int status) {
    toSpeech.mTts.setOnUtteranceCompletedListener(this);
    toSpeech.mTts.setLanguage(Locale.US);
    toSpeech.playVoice(new String[] {"correct answer"}, true); //again start recognition after voice
}   
  

}

 public class TxtToSpeech {
   public TextToSpeech      mTts            = null;
   public Context       ctxt            = null;
   public boolean       recordAnswer    = false;

    public TxtToSpeech(Context context){

        mTts = new TextToSpeech(context, (OnInitListener)context);
        ctxt = context; 
    }       
    public void playVoice(String[] sentences, boolean answer){
        final HashMap<String, String> utteranceMap = new HashMap<String,String>();
        utteranceMap.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "1");

        recordAnswer = answer;

        StringBuilder builder = new StringBuilder();
        for( String s:sentences)
        {
            builder.append(s);
            builder.append(",");
        }
        final String text = builder.toString();

        if( recordAnswer )
            mTts.speak(text, TextToSpeech.QUEUE_ADD, utteranceMap);
        else
            mTts.speak(text, TextToSpeech.QUEUE_ADD, null);
    }
  

}

всегда ли мне нужно перезапускать весь QuestionActivity, чтобы запустить VoiceRecognition? Во время игры пользователь переключается только между вопросом- и AnswerActivity есть ли более приятный способ, чем просто завершить () действия?

Ответ №1:

Пожалуйста, опишите ошибку, которую вы получаете.

В общем, перезапуск действия должен быть обычной частью любого действия Android, поскольку пользователь постоянно переключается. Кроме того, если два действия неудобны, возможно, вы сможете обойтись одним.