android 音乐播放 启动方式 (3)服务通过发送广播来控制activity显示进度等

原项目在这里  https://github.com/LineChen/XimalayaFM

播放列表存放在里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 中
/**
* 通知服务播放对应位置的音乐
* @param position
*/
private void playMusic( int position, boolean playNew){
Intent serviceIntent = new Intent( 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);
}
case R.id. ac_notify_play_ib :
// TODO 点击播放按钮处理
isPlaying = ! isPlaying ;
Log. e ( "--============" , "activity:isPlaying : " + isPlaying );
playMusic(- 1 , false );
// 更新 playUI
updatePlayUI( isPlaying );
break ;
*******************-----------*********************
case R.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 ;

case R.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 void onStopTrackingTouch(SeekBar seekBar) {
int cur = seekBar.getProgress();
Intent intent = new Intent(
Constants. CAST_ACTION_SEEKBAR_PROCESS );
intent.putExtra(Constants. INTENT_EXTRA_MUSIC_CUR_LEN , cur);
lbManager .sendBroadcast(intent);
}
/**
* 自定义广播接受者
*/
class PrgReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO 接收播放服务组件中发送的进度广播
String action = intent.getAction();
if (action.equals(Constants. CAST_ACTION_MUSIC_PROGRESS )) {
int max = intent.getIntExtra(
Constants. INTEXT_EXTRA_MUSIC_TOTAL_LEN , 0 );
int cur = intent.getIntExtra(
Constants. INTENT_EXTRA_MUSIC_CUR_LEN , 0 );
seekBar .setMax(max);
seekBar .setProgress(cur);

nowTimeTv .setText( dateFormat .format( new Date(cur)));
totalTimeTv .setText( dateFormat .format( new Date(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 )){
int progress = intent.getIntExtra(Constants. INTENT_EXTRA_BUFFERING_UPDATE , 0 );
int max = 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 );
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值