Как управлять состоянием Android MediaPlayer, ошибками и исключениями? - PullRequest
4 голосов
/ 25 февраля 2012

Я пытаюсь воспроизвести короткий звуковой байт после обработки отсканированного штрих-кода. Мой код в настоящее время отлично работает для двадцати сканирований. Однако, в конце концов, MediaPlayer неоднократно выдает следующую ошибку, даже после того, как приложение было убрано:

MediaPlayer: Error (-38, 0)

MediaPlayer: Attempt to perform seekTo in wrong state: mPlayer=0xXXXXXX, mCurrentState=0

- X представляют случайный 6-значный адрес памяти -

Первоначально я воспроизводил звук из потока пользовательского интерфейса. Так как я создал обработчик в попытке смягчить проблему. Вот как я получаю доступ к обработчику:

    try {
            mHandler.post(mScanFeedback);
    } catch (IllegalStateException e) {
            System.out.println("Media player state error");
            e.printStackTrace();
    }

Вот код для обработчика:

private Runnable mScanFeedback = new Runnable(){
    public void run() {
        if(getString(R.string.working).equals(mStatusHourly)) {
            final MediaPlayer mediaPlayer = MediaPlayer.create(getBaseContext(), R.raw.bleep_working);
            mediaPlayer.setOnErrorListener(new OnErrorListener() {
                public boolean onError(MediaPlayer mp, int what, int extra) {
                    mediaPlayer.reset();
                    System.out.println("Media Player onError callback!");
                    return true;
                }
            });
            mediaPlayer.start();
            try {
                Thread.sleep(150);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                mediaPlayer.release();
            }
        } else if(getString(R.string.not_working).equals(mStatusHourly)) {
            final MediaPlayer mediaPlayer = MediaPlayer.create(getBaseContext(), R.raw.bleep_not_working);
            mediaPlayer.setOnErrorListener(new OnErrorListener() {
                public boolean onError(MediaPlayer mp, int what, int extra) {
                    mediaPlayer.reset();
                    System.out.println("Media Player onError callback!");
                    return true;
                }
            });

            mediaPlayer.start();
            try {
                Thread.sleep(275);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                mediaPlayer.release();
            }
        } else {
            System.out.println("Audio feedback failed as status was indeterminate.");
        }

    }
};

Вначале я не вызывал release (), и добавление его, похоже, не делало его лучше или хуже. Обратный вызов onError никогда не вызывается при возникновении проблемы. Я пытался сбросить () медиаплеер после каждого воспроизведения, но это выдает ошибку. Прямо сейчас я прибегаю к перезагрузке телефона, чтобы предотвратить невозможность использования Logcat из-за непрерывного повторения тех же двух строк ошибок.

Я использую сканер штрих-кода zxing, и в рамках этого действия воспроизводится короткий звуковой сигнал в качестве подтверждения того, что штрих-код был захвачен. Небольшая часть меня задается вопросом, не является ли их конфликт там.

Я все еще новичок в программировании, и это мой первый вопрос о переполнении стека. Дайте мне знать, если бы мне следовало предоставить какую-либо дополнительную информацию или я должен постараться сделать ее более скудной.

Обновление:

Мне не удалось решить проблему с MediaPlayer. Однако я смог обойти эту проблему, переключившись на реализацию SoundPool. Класс ниже обеспечивает необходимую функциональность.

import java.util.HashMap;

import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;

public class SoundManager {

private  SoundPool mSoundPool;
private  HashMap mSoundPoolMap;
private  AudioManager  mAudioManager;
private  Context mContext;

public void initSounds(Context theContext) {
    mContext = theContext;
    mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
    mSoundPoolMap = new HashMap();
    mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
}

public void addSound(int index, int SoundID) {
    mSoundPoolMap.put(index, mSoundPool.load(mContext, SoundID, 1));
}

public void playSound(int index) {
    float streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
    streamVolume = streamVolume / mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
    mSoundPool.play(index, streamVolume, streamVolume, 1, 0, 1f);
}

public void playLoopedSound(int index) {
    float streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
    streamVolume = streamVolume / mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
    mSoundPool.play(index, streamVolume, streamVolume, 1, -1, 1f);
}
}

К которому я затем получил доступ из своей Деятельности:

mSoundManager = new SoundManager();
mSoundManager.initSounds(getBaseContext());
mSoundManager.addSound(1, R.raw.bleep_working);
mSoundManager.addSound(2, R.raw.bleep_not_working);
mSoundManager.playSound(1);
mSoundManager.playSound(2);
...