在Android中播放音频文件一般都是使用
MediaPlayer
类来实现的
MediaPlayer
使用步骤简介:
-
创建
MediaPlayer
对象MediaPlayer mediaPlayer = new MediaPlayer();
-
将
MediaPlayer
对象重置为刚刚创建的状态mediaPlayer.reset();
-
设置要播放的音频文件的位置(可以是本地文件也可以是网络文件)
mediaPlayer.setDataSource(Environment.getExternalStorageDirectory().getAbsolutePath() + "/richu.mp3");
-
在开始播放之前完成准备工作
-
若播放的是本地文件
mediaPlayer.prepare();
-
若播放的是网络文件
/*异步准备,本地文件也可以使用此方法来进行播放前的准备*/ mediaPlayer.prepareAsync(); /*播放网络音频,不一定会调用完准备方法后直接准备完成,故添加一个准备监听*/ mediaPlayer.setOnPreparedListener(new OnPreparedListener() { /*此方法在准备完成之后调用*/ @Override public void onPrepared(MediaPlayer mp) { } });
-
-
开始播放音频文件
mediaPlayer.start();
-
其他API
-
判断当前
MediaPlayer
是否正在播放音频mediaPlayer.isPlaying();
-
暂停播放音频
mediaPlayer.pause();
-
停止播放音频
mediaPlayer.stop();
调用这个方法后的MediaPlayer对象无法再播放音频
-
释放掉与
MediaPlayer
对象相关的资源mediaPlayer.release();
-
获取载入的音频文件的时长
mediaPlayer.getDuration();
-
获取已播放的音频时长
mediaPlayer.getCurrentPosition();
-
从指定的位置开始播放音频文件
mediaPlayer.seekTo();
-
制作简易音乐播放器
播放音乐需要在服务中进行,当音乐播放器界面不显示的时候,音乐依旧可以播放
1、在服务中,有开始播放、暂停播放、滑动进度条在指定位置播放音乐等方法的定义
2、在服务中,定义一个计时器,根据音乐播放的进度,在进度条SeekBar
中显示出来
3、在活动中,添加进度条SeekBar
监听器
-
MusicService
:public class MusicService extends Service { //操作音频文件的API private static MediaPlayer mediaPlayer; //计时器API private Timer timer; @Override public IBinder onBind(Intent intent) { //活动和服务绑定时,返回MusicControl对象(继承自IBinder对象) return new MusicControl(); } @Override public void onCreate() { super.onCreate(); //创建MediaPlayer对象 mediaPlayer = new MediaPlayer(); } @Override public void onDestroy() { super.onDestroy(); //暂停播放 mediaPlayer.stop(); //释放资源 mediaPlayer.release(); if (timer != null) { //将计时器取消 timer.cancel(); timer = null; } } /*开始播放音乐的方法*/ public void play(){ //重置MediaPlayer对象 mediaPlayer.reset(); try { /*加载多媒体文件*/ //本地加载 mediaPlayer.setDataSource(Environment.getExternalStorageDirectory().getAbsolutePath() + "/richu.mp3"); //网络视频加载
// mediaPlayer.setDataSource("http://192.168.1.101:8080/richu.mp3");
//异步准备
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
//准备完毕时,此方法调用
@Override
public void onPrepared(MediaPlayer mp) {
//开始播放
mediaPlayer.start();
//计时器开始计时
addTimer();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
/*继续播放音乐的方法*/
public void continuePlay(){
mediaPlayer.start();
}
/*暂停播放音乐*/
public void pause(){
mediaPlayer.pause();
}
/*添加一个计时器对象*/
public void addTimer(){
if (timer == null) {
timer = new Timer();
//计时器设置,相当于开启了一个子线程
timer.schedule(new TimerTask() {
@Override
public void run() {
//获取歌曲总时长
int duration = mediaPlayer.getDuration();
//获取歌曲当前播放进度
int currentPosition = mediaPlayer.getCurrentPosition();
/*发送消息对象,在主线程中更新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);//开始计时任务后的5毫秒,第一次执行run方法;以后每500毫秒执行一次
}
}
/*指定位置播放音乐*/
public void seekTo(int progress){
mediaPlayer.seekTo(progress);
}
/*服务和绑定此服务的活动通信的中间对象*/
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
服务和绑定此服务的活动通信的中间对象抽象出来的接口:public interface MusicInterface { void play(); void continuePlay(); void pause(); void seekTo(int progress); }
-
MainActivity
活动界面:public class MainActivity extends Activity { private MyConnection connection; private MusicInterface control; private Intent intent; //进度条对象 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,更新进度条进度 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) { //根据拖动的进度改变音乐的播放进度 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", "手指滑动"); } }); connection = new MyConnection(); intent = new Intent(this, MusicService.class); //开启服务以及绑定服务 startService(intent); bindService(intent, connection, BIND_AUTO_CREATE); } class MyConnection implements ServiceConnection{ @Override public void onServiceConnected(ComponentName name, IBinder service) { //拿到服务和活动通信的中间对象 control = (MusicControl) service; } @Override public void onServiceDisconnected(ComponentName name) { } } /* *通过中间人对象调用服务中的方法来操作音乐的状态 */ 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); } }