Android TTS + WakeLock

У меня есть приложение, которое использует 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();
    }
}

person Sandor Farkas    schedule 30.10.2013    source источник
comment
wakeLock.acquire(1000) получает блокировку пробуждения, которая будет длиться всего 1000 миллисекунд (1 секунду), это слишком мало для того, что вы хотите, не так ли? Вы должны wakeLock.acquire() (таймаут не определен) и wakeLock.release() по окончании TTS.   -  person Piovezan    schedule 30.10.2013
comment
Я подумал, что придется подождать столько же времени, прежде чем заполучить замок. позвольте мне проверить, спасибо!   -  person Sandor Farkas    schedule 30.10.2013
comment
Я удалил 1000, но проблема не исчезла. Кажется, что мое приложение запущено (как я вижу активность в журналах), но TTS перестает работать.   -  person Sandor Farkas    schedule 30.10.2013
comment
Пожалуйста, опубликуйте полный исходный код, чтобы у нас был правильный контекст.   -  person Piovezan    schedule 30.10.2013
comment
Добавил код выше, удалил неважные детали.   -  person Sandor Farkas    schedule 30.10.2013
comment
Где вы декларируете playing? Вы инициализируете его с помощью false? Изменится ли что-то еще за пределами предоставленного вами кода?   -  person Piovezan    schedule 30.10.2013
comment
Да, это только для других частей кода. Поскольку это довольно сложное приложение, я удалил неважные части, но не все проверил. Важно то, что я использую именно эту структуру. Вызов AsyncTask, который запускает TTS, который останавливается при блокировке экрана. :(   -  person Sandor Farkas    schedule 30.10.2013
comment
Что меня беспокоит, так это то, что playing может быть уже false, когда приложение достигает той части while (mTts.isSpeaking()), которая заставляет время немедленно уйти. В противном случае код выглядит нормально. Я бы просто поместил код разблокировки wakelock внутри finally block с соответствующим блоком try, занимающим весь метод doInBackground, чтобы вы могли выполнить return, не оставляя wakelock невыпущенным.   -  person Piovezan    schedule 30.10.2013
comment
Последняя проверка: включили ли вы разрешение android.permission.WAKE_LOCK в свой AndroidManifest.xml?   -  person Piovezan    schedule 30.10.2013
comment
Извините, я забыл об этом упомянуть. Да   -  person Sandor Farkas    schedule 30.10.2013
comment
Что касается переменной воспроизведения: ее цель - следить, работает ли мой плеер или остановлен. Таким образом, если текст воспроизводится через TTS, он постоянно проверяет эту переменную, а если она ложна, то останавливает TTS. Код, который обрабатывает эту часть, исключен из моего примера кода выше.   -  person Sandor Farkas    schedule 30.10.2013
comment
О, я понимаю, что может происходить. onPause() вызывается, когда экран гаснет, и это вызывает остановку TTS. Также в качестве побочного примечания, если вы хотите, чтобы TTS работал более чем в одном действии, вы должны объявить mTts за пределами области действия, поскольку он будет уничтожен вместе с действием при изменении действий.   -  person Piovezan    schedule 30.10.2013
comment
Пиовезан: вы молодец. Это была проблема, мне даже не нужен WakeLock, теперь мое приложение работает как шарм. :) СПАСИБО! : D (О, и если бы вы могли добавить свой комментарий в качестве ответа, я бы с радостью его принял;)   -  person Sandor Farkas    schedule 30.10.2013
comment
Большой. Однако я думаю, что вам понадобится wakelock, если ваш TTS продолжается слишком долго после того, как экран погас, поскольку к этому времени ЦП обычно переходит в спящий режим.   -  person Piovezan    schedule 30.10.2013


Ответы (1)


onPause() вызывается, когда экран гаснет, и это вызывает остановку TTS.

person Piovezan    schedule 30.10.2013