在Android中播放音頻文件一般都是使用
MediaPlayer
類來實(shí)現(xiàn)的
MediaPlayer
使用步驟簡介:
-
創(chuàng)建
MediaPlayer
對象MediaPlayer mediaPlayer = new MediaPlayer();
-
將
MediaPlayer
對象重置為剛剛創(chuàng)建的狀態(tài)mediaPlayer.reset();
-
設(shè)置要播放的音頻文件的位置(可以是本地文件也可以是網(wǎng)絡(luò)文件)
mediaPlayer.setDataSource(Environment.getExternalStorageDirectory().getAbsolutePath() + "/richu.mp3");
-
在開始播放之前完成準(zhǔn)備工作
-
若播放的是本地文件
mediaPlayer.prepare();
-
若播放的是網(wǎng)絡(luò)文件
/*異步準(zhǔn)備弦疮,本地文件也可以使用此方法來進(jìn)行播放前的準(zhǔn)備*/ mediaPlayer.prepareAsync(); /*播放網(wǎng)絡(luò)音頻,不一定會(huì)調(diào)用完準(zhǔn)備方法后直接準(zhǔn)備完成蜘醋,故添加一個(gè)準(zhǔn)備監(jiān)聽*/ mediaPlayer.setOnPreparedListener(new OnPreparedListener() { /*此方法在準(zhǔn)備完成之后調(diào)用*/ @Override public void onPrepared(MediaPlayer mp) { } });
-
-
開始播放音頻文件
mediaPlayer.start();
-
其他API
-
判斷當(dāng)前
MediaPlayer
是否正在播放音頻mediaPlayer.isPlaying();
-
暫停播放音頻
mediaPlayer.pause();
-
停止播放音頻
mediaPlayer.stop();
調(diào)用這個(gè)方法后的MediaPlayer對象無法再播放音頻
-
釋放掉與
MediaPlayer
對象相關(guān)的資源mediaPlayer.release();
-
獲取載入的音頻文件的時(shí)長
mediaPlayer.getDuration();
-
獲取已播放的音頻時(shí)長
mediaPlayer.getCurrentPosition();
-
從指定的位置開始播放音頻文件
mediaPlayer.seekTo();
-
制作簡易音樂播放器
播放音樂需要在服務(wù)中進(jìn)行胁塞,當(dāng)音樂播放器界面不顯示的時(shí)候,音樂依舊可以播放
1压语、在服務(wù)中闲先,有開始播放、暫停播放无蜂、滑動(dòng)進(jìn)度條在指定位置播放音樂等方法的定義
2吓著、在服務(wù)中,定義一個(gè)計(jì)時(shí)器芝雪,根據(jù)音樂播放的進(jìn)度参萄,在進(jìn)度條SeekBar
中顯示出來
3、在活動(dòng)中酣倾,添加進(jìn)度條SeekBar
監(jiān)聽器
-
MusicService
:public class MusicService extends Service { //操作音頻文件的API private static MediaPlayer mediaPlayer; //計(jì)時(shí)器API private Timer timer; @Override public IBinder onBind(Intent intent) { //活動(dòng)和服務(wù)綁定時(shí)舵揭,返回MusicControl對象(繼承自IBinder對象) return new MusicControl(); } @Override public void onCreate() { super.onCreate(); //創(chuàng)建MediaPlayer對象 mediaPlayer = new MediaPlayer(); } @Override public void onDestroy() { super.onDestroy(); //暫停播放 mediaPlayer.stop(); //釋放資源 mediaPlayer.release(); if (timer != null) { //將計(jì)時(shí)器取消 timer.cancel(); timer = null; } } /*開始播放音樂的方法*/ public void play(){ //重置MediaPlayer對象 mediaPlayer.reset(); try { /*加載多媒體文件*/ //本地加載 mediaPlayer.setDataSource(Environment.getExternalStorageDirectory().getAbsolutePath() + "/richu.mp3"); //網(wǎng)絡(luò)視頻加載
// mediaPlayer.setDataSource("http://192.168.1.101:8080/richu.mp3");
//異步準(zhǔn)備
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
//準(zhǔn)備完畢時(shí),此方法調(diào)用
@Override
public void onPrepared(MediaPlayer mp) {
//開始播放
mediaPlayer.start();
//計(jì)時(shí)器開始計(jì)時(shí)
addTimer();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
/*繼續(xù)播放音樂的方法*/
public void continuePlay(){
mediaPlayer.start();
}
/*暫停播放音樂*/
public void pause(){
mediaPlayer.pause();
}
/*添加一個(gè)計(jì)時(shí)器對象*/
public void addTimer(){
if (timer == null) {
timer = new Timer();
//計(jì)時(shí)器設(shè)置躁锡,相當(dāng)于開啟了一個(gè)子線程
timer.schedule(new TimerTask() {
@Override
public void run() {
//獲取歌曲總時(shí)長
int duration = mediaPlayer.getDuration();
//獲取歌曲當(dāng)前播放進(jìn)度
int currentPosition = mediaPlayer.getCurrentPosition();
/*發(fā)送消息對象午绳,在主線程中更新UI*/
Message message = MainActivity.handler.obtainMessage();
Bundle bundle = new Bundle();
bundle.putInt("duration", duration);
bundle.putInt("currentPosition", currentPosition);
message.setData(bundle);
MainActivity.handler.sendMessage(message);
}
}, 5, 500);//開始計(jì)時(shí)任務(wù)后的5毫秒,第一次執(zhí)行run方法映之;以后每500毫秒執(zhí)行一次
}
}
/*指定位置播放音樂*/
public void seekTo(int progress){
mediaPlayer.seekTo(progress);
}
/*服務(wù)和綁定此服務(wù)的活動(dòng)通信的中間對象*/
class MusicControl extends Binder implements MusicInterface{
@Override
public void play() {
MusicService.this.play();
}
@Override
public void continuePlay() {
MusicService.this.continuePlay();
}
@Override
public void pause() {
MusicService.this.pause();
}
@Override
public void seekTo(int progress) {
MusicService.this.seekTo(progress);
}
}
}
```
-
MusicInterface
服務(wù)和綁定此服務(wù)的活動(dòng)通信的中間對象抽象出來的接口:public interface MusicInterface { void play(); void continuePlay(); void pause(); void seekTo(int progress); }
-
MainActivity
活動(dòng)界面:public class MainActivity extends Activity { private MyConnection connection; private MusicInterface control; private Intent intent; //進(jìn)度條對象 private static SeekBar bar; static final int TIME = 0; static Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { Bundle bundle = msg.getData(); int duration = (Integer) bundle.get("duration"); int currentPosition = (Integer) bundle.get("currentPosition"); bar.setMax(duration); //主線程中更新UI拦焚,更新進(jìn)度條進(jìn)度 bar.setProgress(currentPosition); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bar = (SeekBar) findViewById(R.id.sb); bar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { //根據(jù)拖動(dòng)的進(jìn)度改變音樂的播放進(jìn)度 int currentPosition = seekBar.getProgress(); control.seekTo(currentPosition); Log.d("MainActivity", "手指抬起"); } @Override public void onStartTrackingTouch(SeekBar seekBar) { Log.d("MainActivity", "手指按下"); } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { Log.d("MainActivity", "手指滑動(dòng)"); } }); connection = new MyConnection(); intent = new Intent(this, MusicService.class); //開啟服務(wù)以及綁定服務(wù) startService(intent); bindService(intent, connection, BIND_AUTO_CREATE); } class MyConnection implements ServiceConnection{ @Override public void onServiceConnected(ComponentName name, IBinder service) { //拿到服務(wù)和活動(dòng)通信的中間對象 control = (MusicControl) service; } @Override public void onServiceDisconnected(ComponentName name) { } } /* *通過中間人對象調(diào)用服務(wù)中的方法來操作音樂的狀態(tài) */ public void play(View v){ control.play(); } public void continuePlay(View v){ control.continuePlay(); } public void pause(View v){ control.pause(); } public void exit(View v){ unbindService(connection); stopService(intent); } }