У меня есть приложение, которое использует TTS для чтения текста в AsyncTask. Моя проблема в том, что когда телефон засыпает, воспроизведение останавливается. Я просмотрел много тем в этой теме, и все указывает на WakeLock. Однако я не могу его реализовать, независимо от того, вызываю ли я его в классе активности или классе AsyncTask. Я использую следующий код:
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My wakelook");
wakeLock.acquire(1000);
Я предполагаю, что проблема в TTS, но в настоящее время я ничего не понимаю. Может быть, мне поможет кто-нибудь с большим опытом TTS и WakeLock.
заранее спасибо
РЕДАКТИРОВАТЬ:
Вот полный код (неважные части удалены):
public class PlayerActivity extends Activity implements
TextToSpeech.OnInitListener {
// TTS fields
private TextToSpeech mTts;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player);
List<TTSPlayItem> playItems = new ArrayList<TTSPlayItem>();
TTSPlayItem playItem = new TTSPlayItem();
playItem.locale = getLocale1();
playItem.text = getText1();
playItem.position = position;
playItems.add(playItem);
playItem = new TTSPlayItem();
playItem.locale = getLocale2();
playItem.text = getText2();
playItem.position = position;
playItems.add(playItem);
TTSPlayItem[] passPlayItems = playItems
.toArray(new TTSPlayItem[playItems.size()]);
TTSAsyncTask speak = new TTSAsyncTask();
speak.execute(passPlayItems);
}
/*
* AsyncTask for TTS
*/
private class TTSAsyncTask extends
AsyncTask<TTSPlayItem, TTSPlayItem, String> {
// WakeLock
PowerManager pm;
PowerManager.WakeLock wakeLock;
protected void onPreExecute() {
}
@Override
protected String doInBackground(TTSPlayItem... items) {
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My wakelook");
wakeLock.acquire();
for (int i = 0; i < items.length; i++) {
TTSPlayItem[] progressList = new TTSPlayItem[1];
progressList[0] = items[i];
publishProgress(progressList);
Log.i(TAG, "Play - locale: " + items[i].locale.toString()
+ ", text: " + items[i].text);
int treshold = 0;
while (true) {
int result = mTts.setLanguage(items[i].locale);
Log.i(TAG, "Locale return: " + result);
if (result == 1)
break;
if (treshold == 100)
break;
treshold++;
}
mTts.speak(items[i].text, TextToSpeech.QUEUE_FLUSH, null);
while (mTts.isSpeaking()) {
if (playing == false) {
mTts.stop();
return "Playback stopped.";
}
}
// wait
android.os.SystemClock.sleep(1000);
}
playing = false;
if (wakeLock.isHeld())
wakeLock.release();
return "Played list of " + items.length + " items.";
}
protected void onProgressUpdate(TTSPlayItem... result) {
}
protected void onPostExecute(String result) {
}
/*
* TTS methods
*/
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_DATA_CHECK_CODE) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
// success, create the TTS instance
mTts = new TextToSpeech(this, this);
} else {
// missing data, install it
Intent installIntent = new Intent();
installIntent
.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installIntent);
}
}
}
public void shutdownTTS() {
playing = false;
// Don't forget to shutdown!
if (mTts != null) {
mTts.stop();
mTts.shutdown();
}
}
@Override
public void onDestroy() {
shutdownTTS();
super.onDestroy();
}
public void onStop() {
shutdownTTS();
super.onStop();
}
public void onPause() {
shutdownTTS();
super.onPause();
}
}
wakeLock.acquire(1000)
получает блокировку пробуждения, которая будет длиться всего 1000 миллисекунд (1 секунду), это слишком мало для того, что вы хотите, не так ли? Вы должныwakeLock.acquire()
(таймаут не определен) иwakeLock.release()
по окончании TTS. - person Piovezan   schedule 30.10.2013playing
? Вы инициализируете его с помощьюfalse
? Изменится ли что-то еще за пределами предоставленного вами кода? - person Piovezan   schedule 30.10.2013playing
может быть ужеfalse
, когда приложение достигает той частиwhile (mTts.isSpeaking())
, которая заставляет время немедленно уйти. В противном случае код выглядит нормально. Я бы просто поместил код разблокировки wakelock внутри finallyblock
с соответствующим блокомtry
, занимающим весь методdoInBackground
, чтобы вы могли выполнитьreturn
, не оставляя wakelock невыпущенным. - person Piovezan   schedule 30.10.2013android.permission.WAKE_LOCK
в свой AndroidManifest.xml? - person Piovezan   schedule 30.10.2013onPause()
вызывается, когда экран гаснет, и это вызывает остановку TTS. Также в качестве побочного примечания, если вы хотите, чтобы TTS работал более чем в одном действии, вы должны объявитьmTts
за пределами области действия, поскольку он будет уничтожен вместе с действием при изменении действий. - person Piovezan   schedule 30.10.2013