当前位置: 代码迷 >> Android >> 怎么写一个正经的Android音乐播放器 三
  详细解决方案

怎么写一个正经的Android音乐播放器 三

热度:16   发布时间:2016-04-28 03:23:20.0
如何写一个正经的Android音乐播放器 三

实现音乐的播放。

为了快速实现音乐播放,我们使用MediaPlayer而不用SoundPool,据说SoundPool比MediaPlayer的自由度更大。不过,根据我的了解,soundpool并不支持音频的解码,得自己去解码,而MeidaPlayer已经内置了一些解码方案,我看到的是,音频除了ape无损格式,都能播放。

你需要阅读:

MediaPlayer API:

http://developer.android.com/reference/android/media/MediaPlayer.html

MediaPlayer API Guide:

http://developer.android.com/guide/topics/media/mediaplayer.html

在此,不再介绍MediaPlayer的使用。


在途中,我们可以看到MediaPlayer的生命周期,其中,蓝色椭圆内的是Mediaplayer的不同状态。

如果在不允许的状态执行了一些不应该的操作,会出现异常。在进行不同操作时候,合法的前提状态和不合法的状态,参考这个链接:

http://developer.android.com/reference/android/media/MediaPlayer.html#Valid_and_Invalid_States

我们声明一个类来记录状态。

public static class State {        public static final int                IDLE = 0,                INITIALIZED = 1,                PREPARED = 2,                PREPARING = 3,                STARTED = 4,                PAUSED = 5,                STOPPED = 6,                COMPLETED = 7,                END = -1,                ERROR = -2;    }

在我们的MainService中,可以这样写开始播放的代码:

//这个方法用来初始化我们的MediaPlayerprivate void init () {        if (mPlayer == null) {            mPlayer = new MediaPlayer();            changeState(State.IDLE);        } else {            if (mCurrentState == State.IDLE || mCurrentState == State.INITIALIZED || mCurrentState == State.PREPARED ||                    mCurrentState == State.STARTED || mCurrentState == State.PAUSED || mCurrentState == State.STOPPED ||                    mCurrentState == State.COMPLETED || mCurrentState == State.ERROR) {                mPlayer.reset();                changeState(State.IDLE);		//注意状态更改的代码            }        }        mPlayer.setOnErrorListener(this);		//MainService 要实现这三个接口        mPlayer.setOnPreparedListener(this);        mPlayer.setOnCompletionListener(this);    }

对外公开的一个开始播放的方法:

public void start (Audio audio) {        init();        try {            if (mCurrentState == State.IDLE) {                mPlayer.setDataSource(this, audio.getUri());    //Valid Sates IDLE            }            changeState(State.INITIALIZED);            if (mCurrentState != State.ERROR) {                mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);      //Invalid States ERROR            }            if (mCurrentState == State.INITIALIZED || mCurrentState == State.STOPPED) {                mPlayer.prepareAsync();//Valid Sates{Initialized, Stopped}                changeState(State.PREPARING);            }        } catch (IOException e) {            e.printStackTrace();        }    }

注意,在此方法中,我们不要直接去播放,而是使用mPlayer.prepareAsync()。让MediaPlayer去做申请播放资源等工作,这个过程有可能有几十毫秒的耗时,等到回调onPrepared回调成功后,在onPrepared中去做真正的开始播放,我们在onPrepared中调用一下doStart方法:

private void doStart () {        mPlayer.start();        changeState(State.STARTED);    }

这样,就可以开始播放工作了。在以上代码中,都出现了一个changeState方法。如下:

private void changeState (int state) {        mCurrentState = state;        if (mPlaybackListener != null) {            mPlaybackListener.onStateChanged(mCurrentAudio, mCurrentState);        }    }/*这里采用了setOnPlaybackListener的方法,如果有需要,也可以用一个List去保存一个Listener集合,只要在适当的时候进行释放,例如在Service的onDestroy方法中,去把这个List清空掉*/public void setOnPlaybackListener (OnPlaybackListener listener) {        mPlaybackListener = listener;    }    public static interface OnPlaybackListener {        public void onStateChanged (Audio source, int state);    }



  相关解决方案