前面有一個簡單的音樂播放器,能夠簡單的播放歌曲,這裏實現稍微完善的播放器。
音樂播放器
播放服務
- 播放音頻的代碼應該運行在服務中,定義一個播放服務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);
}
}
}
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);
}
}