首先看看MediaPlaer的生命周期
实现流程 : Application–>Framework MediaPlayer.java–>jni–>Library MediaPlayer.cpp–> 解码 –>Driver–> 硬件
生命周期
Idle–>setDataSource–>Initialized–>prepare/prepareAsyn–>prepared–>start 、 pause 、 stop 、 seekTo
播放
private void play(String path){
if (null == mediaPlayer){
mediaPlayer = new MediaPlayer();
//设置准备监听
mediaPlayer.setOnPreparedListener(onPreparedListener);
//设置错误监听
mediaPlayer.setOnErrorListener(onErrorListener);
//设置播放完毕监听
mediaPlayer.setOnCompletionListener(onCompletionListener);
} else {
mediaPlayer.reset();
}
//1、让MediaPlayer进入idle状态
//设置播放的数据源
try {
mediaPlayer.setDataSource(path);
//2、进入initialized状态
//准备
mediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}
private MediaPlayer.OnPreparedListener onPreparedListener = new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
//3 、进入 onPrepared 状态 ( 准备完毕 ) ,可以去 start 、 pause 、 seekTo 、 stop
mp.start();
}
};
控制:
case R.id.btn_play:
if(mPlayer == null){
play("/mnt/sdcard/Music/zmr.mp3");
} else {
if(!mPlayer.isPlaying()){
mPlayer.start();
}
}
break;
case R.id.btn_pause:
if(null != mPlayer && mPlayer.isPlaying()){
mPlayer.pause();
}
break;
case R.id.btn_stop:
if(null != mPlayer){
mPlayer.stop();
mPlayer.release();
mPlayer = null;
}
break;
mPlayer.isPlaying() 检测是否正在播放中
mPlayer.release() 释放资源,建议停止时使用
mPlayer.getDuration() 获取播放的音乐的总时间
mPlayer.getCurrentPosition() 获取当前播放的时间
mPlayer.seekTo(pos) 设置播放位置
关于播放进度
可以使用 Handler 的延迟发送消息的方式循环获取当前时间,更新进度条
1 、准备完毕时设置最大值
private MediaPlayer.OnPreparedListener onPreparedListener = new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
//3 、进入 onPrepared 状态 ( 准备完毕 ) ,可以去 start 、 pause 、 seekTo 、 stop
// 获取总时间
mSeek.setMax(mp.getDuration());
mp.start();
// 更新播放时间
mHandler.sendEmptyMessageDelayed(MSG_UPDATE_POSITION,200);
}
};
2 、定义 Handler 接收消息时更新,并且控制下一次获取的时间 ( 循环 )
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what == MSG_UPDATE_POSITION){
if(mPlayer != null){
int pos = mPlayer.getCurrentPosition(); // 获取当前的播放时间
mSeek.setProgress(pos);
sendEmptyMessageDelayed(MSG_UPDATE_POSITION,200);
}
}
}
};
注意:播放控制中的进度更新
// 暂停时停止更新
if (null != mPlayer && mPlayer.isPlaying()) {
mHandler.removeMessages(MSG_UPDATE_POSITION);
mPlayer.pause();
}
// 播放时恢复更新
if (!mPlayer.isPlaying()) {
mPlayer.start();
mHandler.sendEmptyMessageDelayed(MSG_UPDATE_POSITION,200);
}
// 停止时 ( 停止更新 ) 重置进度条
if (null != mPlayer) {
mHandler.removeMessages(MSG_UPDATE_POSITION);
mPlayer.stop();
mPlayer.release();
mPlayer = null;
mSeek.setProgress(0);
}
拖动进度条的控制
mSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
if(mPlayer!=null && mPlayer.isPlaying()){
mHandler.removeMessages(MSG_UPDATE_POSITION);
}
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
if(mPlayer!=null){
int pos = seekBar.getProgress(); // 获取拖动到的位置
mPlayer.seekTo(pos); // 设置播放位置
if(mPlayer.isPlaying()){
mHandler.sendEmptyMessageDelayed(MSG_UPDATE_POSITION,200);
}
}
}
});
Activity界面跳转的另外一种写法
在布局按钮中添加Tag标记
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.xykj.mediademo.MainActivity">
<Button
android:id="@+id/btn_2_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="音乐播放器"
android:tag="com.xykj.mediademo.MusicPlayerActivity"/>
LinearLayout>
在MainActivity 中的写法
@Override
public void onClick(View v) {
try {
Class cls = Class.forName((String)(v.getTag()));
Intent it = new Intent(this,cls);
startActivity(it);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
这样也可以实现点击跳转!!