Java 如何管理Android MediaPlayer状态、错误和异常?

Java 如何管理Android MediaPlayer状态、错误和异常?,java,android,audio,media-player,media,Java,Android,Audio,Media Player,Media,我试图在处理扫描的条形码后播放一个短的声音字节。我的代码目前可以正常工作多达20次扫描。但是,即使在应用程序被终止后,MediaPlayer最终也会重复抛出以下错误: MediaPlayer: Error (-38, 0) MediaPlayer: Attempt to perform seekTo in wrong state: mPlayer=0xXXXXXX, mCurrentState=0 --X代表一个随机的6位内存地址-- 我最初是在播放UI线程的声音字节。因为我创建了一个处理程

我试图在处理扫描的条形码后播放一个短的声音字节。我的代码目前可以正常工作多达20次扫描。但是,即使在应用程序被终止后,MediaPlayer最终也会重复抛出以下错误:

MediaPlayer: Error (-38, 0)

MediaPlayer: Attempt to perform seekTo in wrong state: mPlayer=0xXXXXXX, mCurrentState=0
--X代表一个随机的6位内存地址--

我最初是在播放UI线程的声音字节。因为我创建了一个处理程序试图缓解这个问题。这是我访问处理程序的方式:

    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.");
        }

    }
};
以下是处理程序的代码:

    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的问题。然而,通过切换到声音池实现,我能够解决这个问题。下面的类提供了所需的功能

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);