如何寫一個正經的Android音樂播放器 三

來源:互聯網
上載者:User

標籤:list   android   音樂   mediaplayer   audio   

實現音樂的播放。

為了快速實現音樂播放,我們使用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);    }



如何寫一個正經的Android音樂播放器 三

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.