#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, поскольку пользователь постоянно переключается. Кроме того, если два действия неудобны, возможно, вы сможете обойтись одним.