Мне трудно понять, как решить эту проблему, я не уверен, правильно ли я настраиваю потоки или возможно ли вообще решить проблему правильно.
Это приложение для Android, которое считывает определенные строки как TTS (используя собственный TTS Android) в определенные моменты времени. Во время этого чтения TTS пользователь должен иметь возможность вмешаться с такими инструкциями, как «Стоп» или «Пауза». Это распознавание осуществляется с помощью iSpeech API.
Наше текущее решение состоит в том, чтобы TTS работал как поток, который будет выводить правильные строки. Как только пользователь нажимает кнопку, чтобы начать распознавание голоса (используя Intent), приложение выполняет распознавание голоса и отлично справляется с этим, но затем TTS больше никогда ничего не выводит. Logcat показывает следующую ошибку:
11-28 02:18:57.072: W/TextToSpeech(16383): ошибка речи: не привязан к движку TTS
Я думал о том, чтобы сделать распознавание голоса собственным потоком, который приостанавливает TTS, но тогда проблема будет заключаться в том, что таймер, управляющий TTS, станет несинхронизированным с тем, что должно быть.
Любые советы или помощь будут оценены.
Соответствующий код, касающийся потока и намерения, приведен ниже:
Нить
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Prevent device from sleeping mid build.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_build_order);
mPlayer = MediaPlayer.create(BuildOrderActivity.this, R.raw.bing);
params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,"stringId");
tts = new TextToSpeech(BuildOrderActivity.this, new TextToSpeech.OnInitListener() {
@SuppressWarnings("deprecation")
public void onInit(int status) {
if(status != TextToSpeech.ERROR)
{
tts.setLanguage(Locale.US);
tts.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {
public void onUtteranceCompleted(String utteranceId) {
mPlayer.start();
}
});
}
}
});
buttonStart = (Button) findViewById(R.id.buttonStartBuild);
buttonStart.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startBuild = new StartBuildRunnable();
Thread t = new Thread(startBuild);
t.start();
}
});
...//code continues oncreate setup for the view}
public class StartBuildRunnable implements Runnable {
public void run() {
double delay;
buildActions = parseBuildXMLAction();
buildTimes = parseBuildXMLTime();
say("Build has started");
delayForNextAction((getSeconds(buildTimes.get(0)) * 1000));
say(buildActions.get(0));
for (int i = 1; i < buildActions.size(); i++)
{
delay = calcDelayUntilNextAction(buildTimes.get(i - 1), buildTimes.get(i));
delayForNextAction((long) (delay * 1000));
say(buildActions.get(i));
//listViewBuildItems.setSelection(i);
}
say("Build has completed");
}
}
Намерение
/**
* Fire an intent to start the speech recognition activity.
* @throws InvalidApiKeyException
*/
private void startRecognition() {
setupFreeFormDictation();
try {
recognizer.startRecord(new SpeechRecognizerEvent() {
@Override
public void onRecordingComplete() {
updateInfoMessage("Recording completed.");
}
@Override
public void onRecognitionComplete(SpeechResult result) {
Log.v(TAG, "Recognition complete");
//TODO: Once something is recognized, tie it to an action and continue recognizing.
// currently recognizes something in the grammar and then stops listening until
// the next button press.
if (result != null) {
Log.d(TAG, "Text Result:" + result.getText());
Log.d(TAG, "Text Conf:" + result.getConfidence());
updateInfoMessage("Result: " + result.getText() + "\n\nconfidence: " + result.getConfidence());
} else
Log.d(TAG, "Result is null...");
}
@Override
public void onRecordingCancelled() {
updateInfoMessage("Recording cancelled.");
}
@Override
public void onError(Exception exception) {
updateInfoMessage("ERROR: " + exception.getMessage());
exception.printStackTrace();
}
});
} catch (BusyException e) {
e.printStackTrace();
} catch (NoNetworkException e) {
e.printStackTrace();
}
}