public class MainrActivity extends Activity {
private MediaPlayer mediaPlayer;
private ImageButton ppIB;
private SeekBar audioSB;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ppIB=(ImageButton) findViewById(R.id.ppIB);
audioSB = (SeekBar) findViewById(R.id.audioSB);
}
//退出程序时,停止播放
@Override
protected void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer=null;
}
public void onClick(View view) throws Exception{
//如果根本没有播放器对象,则需要现得到一个播放器,否则一切操作都是空指针
if(mediaPlayer==null){
String url = "/mnt/sdcard/ttpod/song/Poker Face-Lady GaGa.mp3"; // your URL here
//创建媒体播放器
mediaPlayer = new MediaPlayer();
//设置音频流的类型
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
//设置音频源
mediaPlayer.setDataSource(url);
//普通缓冲加载,缺点:没缓冲完时,下面的代码都不能执行
//mediaPlayer.prepare(); // might take long! (for buffering, etc)
//异步缓冲:如果播放的是网络资源,可能缓冲时间会很长,这是最好用异步缓冲,它
//在新线程中加载数据,加载是不影响下面代码的继续执行
mediaPlayer.prepareAsync();
//弹出一个进度条形的圆形缓冲对话框
showDialog();
//添加缓冲完毕监听器,把缓冲完后要做的事写在里面,不要影响其他代码
mediaPlayer.setOnPreparedListener(prelistener);
//以下两行注释掉的代码写到缓存完毕监听器对象的方法中取
/* mediaPlayer.start();
//另写一个函数来控制进度条的自动行走
handleSeekbar();*/
//设置当播放器完成播放后的事件监听
mediaPlayer.setOnCompletionListener(comlistener);
}
//如果非空(已经有了播放器对象了,不会空指针)而且是正在播放,点击按钮,就可以把播放器停止下来
else if(mediaPlayer.isPlaying()){
mediaPlayer.pause();
}
//如果非空且已经暂停了,点击按钮就可以开始播放
else {
mediaPlayer.start();
}
//控制按钮的图形:判断当前是否在播放,是设置为播放按钮,不是设置为停止按钮
ppIB.setImageResource(mediaPlayer.isPlaying()?android.R.drawable.ic_media_pause:android.R.drawable.ic_media_play);
}
private void handleSeekbar() {
// TODO Auto-generated method stub
//设置进度条的相对最大值为播放器所播放的音乐的持续时间
audioSB.setMax(mediaPlayer.getDuration());
//开启新线程设置进度条每一秒的位置
new Thread(){
@Override
public void run() {
//开启循环,不停的设置进度条的即时位置
while(mediaPlayer!=null){
//只有播放器正在播放,而且它的进度条没有被拖动时,才能设置进度条的动作
if(mediaPlayer.isPlaying()&&!audioSB.isPressed())
audioSB.setProgress(mediaPlayer.getCurrentPosition());
try {
//一秒钟动一下
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
//为了能拖动进度条来播放,对进度条进行拖动事件的监听
audioSB.setOnSeekBarChangeListener(listener);
}
//利用内部类完成创建播放器播放完成事件监听对象
private OnCompletionListener comlistener=new OnCompletionListener(){
//当播完一首歌后,停止播放器,释放对象资源,等待回收,进度条回到开始,按钮变为开始按钮
@Override
public void onCompletion(MediaPlayer mp) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer=null;
audioSB.setProgress(0);
ppIB.setImageResource(android.R.drawable.ic_media_play);
}
};
//利用内部类完成创建进度条改变监听器对象。
private OnSeekBarChangeListener listener=new OnSeekBarChangeListener() {
@Override
//当不再拖动进度条时监听
public void onStopTrackingTouch(SeekBar seekBar) {
//当播放器对象已经存在(避免了还没播放就拖动时播放器对象的空指针异常)拖到哪里,就从哪里开始播
if(mediaPlayer!=null)
mediaPlayer.seekTo(audioSB.getProgress());
}
@Override
//当点住进度条的时候监听
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
}
};
OnPreparedListener prelistener=new OnPreparedListener(){
@Override
public void onPrepared(MediaPlayer mp) {
//缓冲完了取消提示对话框
dialog.dismiss();
mediaPlayer.start();
//另写一个函数来控制进度条的自动行走
handleSeekbar();
//缓冲完了就可以点击播放,改变按钮形状了,如果这里不写这一句,外面点播放,在缓冲时,还没有播放器对象,所以按钮图标也不会改变
ppIB.setImageResource(mediaPlayer.isPlaying()?android.R.drawable.ic_media_pause:android.R.drawable.ic_media_play);
}
};
private ProgressDialog dialog;
//弹出一个进度条型对话框
public void showDialog(){
dialog = new ProgressDialog(this);
//样式为圆形
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
//显示几行信息
dialog.setMessage("正在缓冲请稍后...");
//此对话框不可以被取消,挡住后面的界面
dialog.setCancelable(false);
dialog.show();
}
}