Androidx學習筆記(77)--- 音樂播放器2

前面有一個簡單的音樂播放器,能夠簡單的播放歌曲,這裏實現稍微完善的播放器。

音樂播放器

播放服務

  • 播放音頻的代碼應該運行在服務中,定義一個播放服務MusicService
  • 服務裏定義play、stop、pause、continuePlay等方法

        private void play() {
            // TODO Auto-generated method stub
            player.reset();
            try {
                player.setDataSource("sdcard/bzj.mp3");
                player.prepare();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            player.start();
    
        }
        private void pause() {
            player.pause();
        }
        private void stop() {
            player.stop();
        }
        private void continuePlay() {
            player.start();
        }
    
  • 把這幾個方法抽取成一個接口MusicInterface
  • 定義一箇中間人類,繼承Binder,實現MusicInterface
  • 先start啓動MusicService,再bind

    Intent intent = new Intent(this, MusicService.class);
    startService(intent);
    bindService(intent, conn, BIND_AUTO_CREATE);
    

根據播放進度設置進度條

  • 獲取當前的播放時間和當前音頻的最長時間

    int currentPosition = player.getCurrentPosition();
    int duration = player.getDuration();
    
  • 播放進度需要不停的獲取,不停的刷新進度條,使用計時器每500毫秒獲取一次播放進度
  • 發消息至Handler,把播放進度放進Message對象中,在Handler中更新SeekBar的進度

    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
    
        @Override
        public void run() {
            int currentPosition = player.getCurrentPosition();
            int duration = player.getDuration();
            Message msg = Message.obtain();
            //把播放進度存入Message中
            Bundle data = new Bundle();
            data.putInt("currentPosition", currentPosition);
            data.putInt("duration", duration);
            msg.setData(data);
            MainActivity.handler.sendMessage(msg);
        }
    }, 5, 500);
    
  • 在Activity中定義Handler

    static Handler handler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            //取出消息攜帶的數據
            Bundle data = msg.getData();
            int currentPosition = data.getInt("currentPosition");
            int duration = data.getInt("duration");
    
            //設置播放進度
            sb.setMax(duration);
            sb.setProgress(currentPosition);
        };
    };
    

拖動進度條改變播放進度

     //給sb設置一個拖動偵聽
     sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
        //停止拖動時調用
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            // TODO Auto-generated method stub
            int progress = seekBar.getProgress();
            mi.seekTo(progress);
        }
        //開始拖動時調用           
        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            // TODO Auto-generated method stub

        }
        //拖動的時候不斷調用         
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            // TODO Auto-generated method stub

        }
    }); 


中間人接口
public interface MusicInterface {
 
void play();
void pause();
void continuePlay();
void seekTo(int progress);
}


服務
public class MusicService extends Service {
 
MediaPlayer player;
private Timer timer;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return new MusicController();
}
 
class MusicController extends Binder implements MusicInterface{
 
@Override
public void play() {
MusicService.this.play();
}
 
@Override
public void pause() {
MusicService.this.pause();
}
 
@Override
public void continuePlay() {
MusicService.this.continuePlay();
}
 
@Override
public void seekTo(int progress) {
MusicService.this.seekTo(progress);
}
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
player = new MediaPlayer();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
//停止播放
player.stop();
//釋放佔用的資源,此時player對象已經廢掉了
player.release();
player = null;
if(timer != null){
timer.cancel();
timer = null;
}
}
//播放音樂
public void play(){
//重置
player.reset();
try {
//加載多媒體文件
player.setDataSource("sdcard/zxmzf.mp3");
// player.setDataSource("http://192.168.13.119:8080/bzj.mp3");
// player.prepare();          //同步
player.prepareAsync(); //異步
// player.start();
player.setOnPreparedListener(new OnPreparedListener() {
//準備完畢時,此方法調用
@Override
public void onPrepared(MediaPlayer mp) {
player.start();
addTimer();
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//繼續播放
public void continuePlay(){
player.start();
}
//暫停播放
public void pause(){
player.pause();
}
public void seekTo(int progress){
player.seekTo(progress);
}
public void addTimer(){
if(timer == null){
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
//獲取歌曲總時長
int duration = player.getDuration();
//獲取歌曲當前播放進度
int currentPosition= player.getCurrentPosition();
Message msg = MainActivity.handler.obtainMessage();
//把進度封裝至消息對象中
Bundle bundle = new Bundle();
bundle.putInt("duration", duration);
bundle.putInt("currentPosition", currentPosition);
msg.setData(bundle);
MainActivity.handler.sendMessage(msg);
}
//開始計時任務後的5毫秒,第一次執行run方法,以後每500毫秒執行一次
}, 5, 500);
}
}
}


Activity
public class MainActivity extends Activity {
 
static Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
Bundle bundle = msg.getData();
int duration = bundle.getInt("duration");
int currentPostition = bundle.getInt("currentPosition");
//刷新進度條的進度
sb.setMax(duration);
sb.setProgress(currentPostition);
}
};
MusicInterface mi;
private MyserviceConn conn;
private Intent intent;
private static SeekBar sb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sb = (SeekBar) findViewById(R.id.sb);
sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
//根據拖動的進度改變音樂播放進度
int progress = seekBar.getProgress();
//改變播放進度
mi.seekTo(progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
}
});
intent = new Intent(this, MusicService.class);
startService(intent);
conn = new MyserviceConn();
bindService(intent, conn, BIND_AUTO_CREATE);
}
 
class MyserviceConn implements ServiceConnection{
 
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mi = (MusicInterface) service;
}
 
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
}
public void play(View v){
mi.play();
}
public void continuePlay(View v){
mi.continuePlay();
}
public void pause(View v){
mi.pause();
}
public void exit(View v){
unbindService(conn);
stopService(intent);
}
 
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章