1. 程式人生 > >android 音樂播放 啟動方式 (3)服務通過傳送廣播來控制activity顯示進度等

android 音樂播放 啟動方式 (3)服務通過傳送廣播來控制activity顯示進度等

播放列表存放在裡application中,這個地方可以優化

1 PlayService中:播放路徑從intent中獲取
 @Override
public void onCreate() {
    super.onCreate();
    mPlayer = new MediaPlayer();  //設定播放完成的監聽 mPlayer.setOnCompletionListener(PlayService.this);
    //設定非同步準備的監聽mPlayer.setOnPreparedListener(this);
    mPlayer.setOnBufferingUpdateListener(this);//Register a callback to be invoked when the status of a network stream's buffer has changed.
    // 獲取本地廣播管理器
    lbManager = LocalBroadcastManager.getInstance(getApplicationContext());
    proReceiver = new ProReceiver();
    lbManager.registerReceiver(proReceiver, new IntentFilter(Constants.CAST_ACTION_SEEKBAR_PROCESS));
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // 判斷是否播放新的歌曲
    if (intent != null) {
        if (intent.getBooleanExtra(Constants.INTENT_EXTRA_CHANGE_MUSIC, false)) {
            // 獲取播放路徑   String path = intent.getStringExtra(Constants.INTENT_EXTRA_MUSIC_PATH);
            curPosition = intent.getIntExtra(Constants.INTENT_EXTRA_MUSIC_POSITION, -1);
            if(curPosition > -1 && curPosition < FMApplication.INSTANCE.getPlayList().size()){
                playMusic(curPosition);
            }
        }else {
            if (mPlayer.isPlaying()) {
                mPlayer.pause();// 暫停
            } else {
                mPlayer.start();// 播放
                new ProgressThread().start();//啟動進度執行緒
            }
        }
    }
    return super.onStartCommand(intent, flags, startId);
}
/**
 * 播放音樂
 * @param position
 */
private void playMusic(int position){
    if(position >= 0 && position < FMApplication.INSTANCE.getPlayList().size()){
        String path = FMApplication.INSTANCE.getPlayList().get(position).getPlayUrl64();
        //播放新歌曲 - reset
        mPlayer.reset();
        try {
            mPlayer.setDataSource(path);
            mPlayer.prepareAsync();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
/**
 * 播放一首音樂結束的回撥方法,傳送播放完畢的廣播
 * @param mediaPlayer
 */
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
    if(++curPosition == FMApplication.INSTANCE.getPlayList().size())
        curPosition = 0;
    playMusic(curPosition);

    // TODO 傳送播放完畢的廣播
    Intent intent = new Intent(Constants.CAST_ACTION_MUSIC_COMPLETE);
    intent.putExtra(Constants.INTENT_EXTRA_MUSIC_POSITION, curPosition);
    lbManager.sendBroadcast(intent);
}
/**
 * 快取資料成功回撥
 * @param mediaPlayer
 */
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
    if (mPlayer.isPlaying()) {
        mPlayer.pause();// 暫停
    } else {
        mPlayer.start();// 播放
        new ProgressThread().start();//啟動進度執行緒
        // TODO 傳送開始播放廣播給 PlayActivity
        Intent intent = new Intent(Constants.CAST_ACTION_MUSIC_START);
        lbManager.sendBroadcast(intent);
    }
}
/**
 * 快取
 * @param mediaPlayer
 * @param progress
 */
@Override
public void onBufferingUpdate(MediaPlayer mediaPlayer, int progress) {
    // TODO 傳送開始播放廣播給 PlayActivity
    Intent intent = new Intent(Constants.CAST_ACTION_BUFFERING_UPDATE);
    sumLen = mPlayer.getDuration();
    if(progress != 100){
        progress = (int) (progress / 100f  *  sumLen);
        intent.putExtra(Constants.INTENT_EXTRA_BUFFERING_UPDATE, progress);
        intent.putExtra(Constants.INTEXT_EXTRA_MUSIC_TOTAL_LEN, sumLen);總時長
        lbManager.sendBroadcast(intent);
    }
}
/**
 * 計算播放進度的執行緒
 */
class ProgressThread extends Thread {
    @Override
    public void run() {
        try {
            while (mPlayer != null && mPlayer.isPlaying()) {
                sumLen = mPlayer.getDuration();
                int currentPosition = mPlayer.getCurrentPosition();
                // 準備傳送進度廣播
                Intent intent = new Intent(Constants.CAST_ACTION_MUSIC_PROGRESS);
                intent.putExtra(Constants.INTEXT_EXTRA_MUSIC_TOTAL_LEN, sumLen);
                intent.putExtra(Constants.INTENT_EXTRA_MUSIC_CUR_LEN, currentPosition);
                lbManager.sendBroadcast(intent);

                Thread.sleep(500);//200ms發一次 ,必須大於0,否則 ANR
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
/**
 * 進度廣播接收者
 */
class ProReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        int cur = intent.getIntExtra(Constants.INTENT_EXTRA_MUSIC_CUR_LEN, 0);//從播放介面傳送過來的進度

        mPlayer.seekTo(cur);
    }
}
@Override
public void onDestroy() {
    super.onDestroy();
    lbManager.unregisterReceiver(proReceiver);
    mPlayer.release();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

2 activity 中 /** *通知服務播放對應位置的音樂 *@paramposition */ private voidplayMusic(intposition,booleanplayNew){ Intent serviceIntent =newIntent(this, PlayService.class); serviceIntent.putExtra(Constants.INTENT_EXTRA_CHANGE_MUSIC, playNew); if(playNew){ if(position > -1&& position < FMApplication.
INSTANCE.getPlayList().size()) serviceIntent.putExtra(Constants.INTENT_EXTRA_MUSIC_POSITION, position); } startService(serviceIntent); } caseR.id.ac_notify_play_ib: //TODO點選播放按鈕處理 isPlaying= !isPlaying; Log.e("--============","activity:isPlaying : "+isPlaying); playMusic(-1,false); //更新playUI updatePlayUI(
isPlaying); break; *******************-----------********************* caseR.id.ac_notify_pre_ib: //TODO點選上一首按鈕處理 if(--curPlayPosition== -1) curPlayPosition= FMApplication.INSTANCE.getPlayList().size() - 1; playMusic(curPlayPosition,true); notifyPlayIb.setEnabled(false); notifyPlayIb.setBackgroundResource(R.drawable.notify_pause_selector); updateOtherUI(curPlayPosition); break; caseR.id.ac_notify_next_ib: //TODO點選下一首按鈕處理 if(++curPlayPosition== FMApplication.INSTANCE.getPlayList().size()) curPlayPosition=0; playMusic(curPlayPosition,true); notifyPlayIb.setEnabled(false); notifyPlayIb.setBackgroundResource(R.drawable.notify_pause_selector); updateOtherUI(curPlayPosition); break; ********************************** //-------------------------seekBar回撥方法 @Override public voidonStopTrackingTouch(SeekBar seekBar) { intcur = seekBar.getProgress(); Intent intent =newIntent( Constants.CAST_ACTION_SEEKBAR_PROCESS); intent.putExtra(Constants.INTENT_EXTRA_MUSIC_CUR_LEN, cur); lbManager.sendBroadcast(intent); } /** *自定義廣播接受者 */ classPrgReceiverextendsBroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //TODO接收播放服務元件中傳送的進度廣播 String action = intent.getAction(); if(action.equals(Constants.CAST_ACTION_MUSIC_PROGRESS)) { intmax = intent.getIntExtra( Constants.INTEXT_EXTRA_MUSIC_TOTAL_LEN,0); intcur = intent.getIntExtra( Constants.INTENT_EXTRA_MUSIC_CUR_LEN,0); seekBar.setMax(max); seekBar.setProgress(cur); nowTimeTv.setText(dateFormat.format(newDate(cur))); totalTimeTv.setText(dateFormat.format(newDate(max))); }else if(action.equals(Constants.CAST_ACTION_MUSIC_COMPLETE)) { //接收service發的播放完成的通知 notifyPlayIb.setBackgroundResource(R.drawable.notify_play_selector); //正常播放完成,直接跳到下一首 curPlayPosition= intent.getIntExtra(Constants.INTENT_EXTRA_MUSIC_POSITION, -1); //更新UI updateOtherUI(curPlayPosition); //播放完成,這段時間還沒開始播放-- isPlaying=false; notifyPlayIb.setEnabled(false); updatePlayUI(isPlaying); }else if(action.equals(Constants.CAST_ACTION_MUSIC_START)){ //TODO開始播放 // notifyPlayIb.setBackgroundResource(R.drawable.notify_pause_selector); isPlaying=true; notifyPlayIb.setEnabled(true); updatePlayUI(isPlaying); }else if(action.equals(Constants.CAST_ACTION_BUFFERING_UPDATE)){ intprogress = intent.getIntExtra(Constants.INTENT_EXTRA_BUFFERING_UPDATE,0); intmax = intent.getIntExtra(Constants.INTEXT_EXTRA_MUSIC_TOTAL_LEN,0); seekBar.setMax(max); seekBar.setSecondaryProgress(progress); // Log.e("--=====----==", "max:" + max + "senProgress:" + progress); } } } @Override public void onDestroy() { super.onDestroy(); lbManager.unregisterReceiver(prgReceiver); }