Android歌詞秀設計思路(3)通用的音樂播放服務(上)

來源:互聯網
上載者:User

MediaPlayerService作為通用的音樂播放Service類,它的功能有:
控制音樂播放,停止,暫停,前/後歌曲切換。
Audio Focus相關處理(對應應用程式切換)。
Intent處理(對應多媒體鍵,耳機線拔出,打入電話)
Notification處理
其實這個類本來是和LyricPlayerService在一起的,但是隨著功能的增加代碼越來越亂。於是就有了分開的想法。但是分也要分出點名堂,於是為這個類定義的功能就是實現一個通用的媒體播放服務。
分開後的類別關係可以從下面的全體圖中看出。

下面針對各功能加以說明
控制音樂播放,停止,暫停,前/後歌曲切換。
在開始真正的工作之前要解決的一個問題是:作為通用的音樂播放那個服務,就一定會還有在後台時播放前/後一首歌的要求。但是這是應用已經不存在了,不可能把這個任務交個Activie來處理。為瞭解決這個問題定義了一個用於取得相應的媒體檔案資訊的MediaInfoProvider類。
public interface MediaInfoProvider{ 
    String getUrl(); 
    String getTitle(); 
    boolean moveToNext(); 
    boolean moveToPrev(); 
}
通過調用moveToNext和moveToPrev方法實現媒體檔案的切換,然後通過調用getUrl和getTitle來取得檔案的資訊。
注意在這裡只是規定介面,真正的執行個體必須由利用者通過下面的方法來提供。有一點額外的工作就是如果希望播放的歌曲和現正播放的不一樣的話就先停止現正播放的歌曲。
public void setMediaInfoProvider(MediaInfoProvider provider) {   
    if( mDataSource != provider.getUrl() && (isStop() == false)){ 
        stop(); 
    } 
    mMediaInfoProvider = provider; 
    mDataSource = provider.getUrl(); 
    mTitle = provider.getTitle(); 

當然在利用MediaPlayer之前我們需要onCreate方法中進行一些準備工作。內容包括
建立MediaPlayer對象,
設定喚醒方式(目的是防止播放中CPU進入休眠狀態,記得在 AndroidManifest.xml中設定許可權為android.permission.WAKE_LOCK)
指定播放完了後的監聽器。
mMediaPlayer = new MediaPlayer(); 
mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK); 
mMediaPlayer.setOnCompletionListener(this);
 
這個播放完了監聽器的目的有兩個。一個是停止工作列上的表徵圖顯示,另外一個是在沒有前台應用的時候自動關閉本服務。要是沒有人管了怎麼辦?對吧。
@Override
    public void onCompletion(MediaPlayer mp) { 
        mIsPausing = false; 
        mNotificationManager.cancel(NOTIFICATION); 
        if(mBinded == false){ 
            stopSelf(); 
        } 
    }  
然後就是onDestroy中進行適當的收尾工作。其中停止播放的部分看起來好像沒有也可以,還是一切都按部就班好一些吧。
mMediaPlayer.setOnCompletionListener(null); 
if(!isStop()){ 
    stop(); 

mMediaPlayer.release(); 
mMediaPlayer = null;
 終於到到了真正的控制部分。接下來的程式比較長但內容確實比較簡單。
在最前面的start方法比較複雜,主要是因為雖然說起來都是播放,但是從暫停恢複播放和播放新歌的處理有所不同。其他的沒有什麼好講的。
public void start() { 
        tryToGetAudioFocus(); 
        if(!isPausing()){ 
            if(isPlaying()){ 
                stop(); 
            } 
            try{    
                mMediaPlayer.reset();    
                mMediaPlayer.setDataSource(mDataSource);    
                mMediaPlayer.prepare();  
            }catch(IOException e) {    
                return;    
            } catch  (IllegalArgumentException e) {    
                return;    
            }    
            mMediaPlayer.start(); 
        }else{ 
            mIsPausing = false; 
            mMediaPlayer.start(); 
        } 
        showNotification(); 
    }    
     
    public void stop() { 
        giveUpAudioFocus(); 
        mMediaPlayer.stop();   
        mIsPausing = false; 
        mNotificationManager.cancel(NOTIFICATION); 
    }    
     
    public void pause() { 
        giveUpAudioFocus(); 
        mIsPausing = true; 
        mMediaPlayer.pause(); 
    } 
     
    public void playNext(){ 
        if(mMediaInfoProvider.moveToNext()){ 
            if(isPlaying() || isPausing()){ 
                stop(); 
            } 
            mDataSource = mMediaInfoProvider.getUrl(); 
            mTitle = mMediaInfoProvider.getTitle(); 
            start(); 
        } 
    } 
     
    public void playPrev(){ 
        if(mMediaInfoProvider.moveToPrev()){ 
            if(isPlaying() || isPausing()){ 
                stop(); 
            } 
            mDataSource = mMediaInfoProvider.getUrl(); 
            mTitle = mMediaInfoProvider.getTitle(); 
            start(); 
        } 
    } 
     
    public boolean isPausing(){ 
        return mIsPausing; 
    } 
     
    public boolean isPlaying() {    
        return mMediaPlayer.isPlaying();    
    }   
     
    public boolean isStop(){ 
        return (isPlaying() == false && isPausing() == false); 
    } 
     
    public int getDuration() {    
        return mMediaPlayer.getDuration();    
    }    
        
    public int getPosition() {    
        return mMediaPlayer.getCurrentPosition();    
    }    
     
    public long seek(long whereto) { 
        mMediaPlayer.seekTo((int ) whereto); 
        return whereto; 
    }
下面的代碼的功能是處理各種有關播放控制的Intent。媒體鍵(就是其實就是線控上的那幾個鈕),耳機線拔出,來電暫停都是通過這種方式實現的。當然它們都需要在AndroidManifest.xml中進行定義。
public static final String ACTION_PAUSE = "MediaPlayer.xwg.action.PAUSE"; 
public static final String ACTION_PLAY_PAUSE = "MediaPlayer.xwg.action.PLAY_PAUSE"; 
public static final String ACTION_PREVIOUS = "MediaPlayer.xwg.action.PREVIOUS"; 
public static final String ACTION_NEXT = "MediaPlayer.xwg.action.NEXT"; 
   @Override
public int onStartCommand(Intent intent, int flags, int startId) { 
    String action = intent.getAction(); 
    if(action != null) 
    { 
        if (action.equals(ACTION_PLAY_PAUSE)){ 
            if(isPlaying()){ 
                pause(); 
            }else{ 
                start(); 
            } 
        }else if (action.equals(ACTION_PAUSE)){ 
            if(isPlaying()) 
            { 
                pause(); 
            } 
        }else if (action.equals(ACTION_PREVIOUS)){ 
            if(isPlaying() || isPausing()) 
            { 
                playPrev(); 
            } 
        }else if (action.equals(ACTION_NEXT)){ 
            if(isPlaying() || isPausing()) 
            { 
                playNext(); 
            } 
        } 
    } 
       return START_NOT_STICKY; // Means we started the service, but don't want it to 
           // restart in case it's killed. 
}
其實在前面代碼中的有幾個地方沒有提,就是關於AudioFocus和MEDIA_BUTTOn,,耳機插頭拔出,來電處理和Notification表示的部分。關於這部分內容請參閱
Android歌詞秀設計思路(4)通用的音樂播放服務(下)
軟體功能說明:原創:Android應用開發-Andorid歌詞秀,含源碼
工程,源碼下載:Android歌詞秀源碼,工程檔案2011/9/11版
 
 
作者“來自大連”

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.