1 create方式创建MediaPlayer进度条设置的代码
package com.android.test;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
public class Test extends Activity {
private Button button1;
private Button button2;
private SeekBar seekBar1;
private MediaPlayer player;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
findView();
setListener();
}
private void init() {
player = MediaPlayer.create(this, R.drawable.example);
}
private void findView() {
button1 = (Button)findViewById(R.id.button1);
button2 = (Button)findViewById(R.id.button2);
seekBar1 = (SeekBar)findViewById(R.id.seekbar1);
//获得歌曲的长度并设置成播放进度条的最大值
seekBar1.setMax(player.getDuration());
}
Handler handler = new Handler();
Runnable updateThread = new Runnable(){
public void run() {
//获得歌曲现在播放位置并设置成播放进度条的值
seekBar1.setProgress(player.getCurrentPosition());
//每次延迟100毫秒再启动线程
handler.postDelayed(updateThread, 100);
}
};
private void setListener() {
button1.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View arg0){
player.start();
//启动
handler.post(updateThread);
}
});
button2.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View arg0) {
player.stop();
//取消线程
handler.removeCallbacks(updateThread);
}
});
seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// fromUser判断是用户改变的滑块的值
if(fromUser==true){
player.seekTo(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
});
}
}
以上设置进度条最大长度seekBar.setMax(mediaPlayer.getDuration());和设置进度条位置seekBar.setProgress(mediaPlayer.getCurrentPosition());以及拖动进度条设置播放位置都只能用于放在资源文件里面的example.mp3文件的播放,对于手机内存以及网络资源音频文件的播放则不行。需要对音频播放位置与进度条进行一个对应换算,一下是换算方式:
播放位置换算成进度条位置:
int position = mediaPlayer.getCurrentPosition();
int time = mediaPlayer.getDuration();
int max = seekBar.getMax();
seekBar.setProgress(position*max/time);
进度条位置换算成播放位置:
int time = mediaPlayer.getDuration();
int max = seekBar.getMax();
2 SetDataSource加载音乐数据进度条设置
package com.multimediademo7audiohttpplayer;
import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
public class AudioHTTPPLayer extends Activity implements OnCompletionListener,
OnErrorListener, OnBufferingUpdateListener, OnPreparedListener,
OnSeekBarChangeListener,OnClickListener {
private MediaPlayer mediaPlayer;
private Button startButton, stopButton, pauseButton;
private TextView statusTextView, bufferValueTextView;
//进度条
private SeekBar seekBar;
//处理进度条更新
Handler handler=new Handler();
//开辟一个线程用于监听歌曲的播放进度
Runnable updateThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_audio_httpplayer);
init();
}
/**
* 实例化组件
*/
private void init() {
startButton = (Button) findViewById(R.id.startButton);
stopButton = (Button) findViewById(R.id.stopButton);
pauseButton = (Button) findViewById(R.id.pauseButton);
statusTextView = (TextView) findViewById(R.id.statusDisplayTextView);
bufferValueTextView = (TextView) findViewById(R.id.bufferValueTextView);
seekBar=(SeekBar)findViewById(R.id.seekBar);
pauseButton.setOnClickListener(this);
startButton.setOnClickListener(this);
stopButton.setOnClickListener(this);
//设置OnSeekBarChangeListener监听器
seekBar.setOnSeekBarChangeListener(this);
statusTextView.setText("onCreate");
mediaPlayer = new MediaPlayer();//定义了一个MediaPlayer对象,整个程序就是围绕这个对象进行操作。这里mediaplayer状态是Idle。
mediaPlayer.setOnCompletionListener(this);//建立Playback是否结束监听
mediaPlayer.setOnErrorListener(this);//建立抛出的错误监听
mediaPlayer.setOnBufferingUpdateListener(this);//建立缓冲的更新监听
mediaPlayer.setOnPreparedListener(this);//建立准备状态监听
statusTextView.setText("MediaPlayer created");
try {
/**
* 调用setDataSource()方法;它将在后台开始缓冲音频文件并返回
* 调用该方法后,MediaPlayer对象由Idle状态进入Initial状态
*/
mediaPlayer.setDataSource("http://yinyueshiting.baidu.com/data2/music/239130183/1226741191428213661128.mp3?xcode=1b9eb60706fc27ee25a63c55f78d2a8bc3ba3c8b80064e3b");
} catch (Exception e) {
e.printStackTrace();
}
statusTextView.setText("setDataSource done");
statusTextView.setText("calling prepareAsync");
mediaPlayer.prepareAsync();
updateThread=new Runnable(){
public void run(){
//活动歌曲现在播放位置并设置成播放进度条的值
int position = mediaPlayer.getCurrentPosition();
int time = mediaPlayer.getDuration();
int max = seekBar.getMax();
seekBar.setProgress(position*max/time);
//每次延迟100毫秒再启动线程
handler.postDelayed(updateThread, 100);
}
};
}
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
bufferValueTextView.setText("" + percent + "%");
}
@Override
public void onPrepared(MediaPlayer mp) {
statusTextView.setText("onPrepared called");
startButton.setEnabled(true);
}
@Override
public void onCompletion(MediaPlayer mp) {
statusTextView.setText("onCompletion called");
startButton.setEnabled(true);
stopButton.setEnabled(false);
}
@Override
protected void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
Log.d("zhongyao", "onDestroy()");
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
statusTextView.setText("onError called");
switch (what) {
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
statusTextView
.setText("MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK"
+ extra);
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
statusTextView.setText("MEDIA_ERROR_SERVER_DIED" + extra);
break;
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
statusTextView.setText("MEDIA_ERROR_UNKNOWN");
break;
default:
break;
}
return false;
}
@Override
public void onClick(View v) {
if (v == startButton) {
mediaPlayer.start();
statusTextView.setText("start called");
startButton.setEnabled(false);
pauseButton.setEnabled(true);
stopButton.setEnabled(true);
//启动进度条线程
handler.post(updateThread);
} else if (v == pauseButton) {
mediaPlayer.pause();
statusTextView.setText("pause called");
stopButton.setEnabled(true);
startButton.setEnabled(true);
pauseButton.setEnabled(false);
}else if (v == stopButton) {
mediaPlayer.stop();
this.init();
statusTextView.setText("stop called");
startButton.setEnabled(true);
pauseButton.setEnabled(false);
stopButton.setEnabled(false);
//取消进度条线程
handler.removeCallbacks(updateThread);
}
}
/**
* 以下三个是OnSeekCompleteListener事件处理接口实现方法
*/
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// TODO Auto-generated method stub
int time = mediaPlayer.getDuration();
int max = seekBar.getMax();
//fromUser判断是否是用户改变的滑块的值
if(fromUser){
mediaPlayer.seekTo(progress*time/max);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
}
3 纠正
其实两种MediaPlayer的创建方式的进度条设置不存在什么差异,只不过setDataSource创建方式中,seekBar.setMax(mediaPlayer.getDuration());必须放在onPrepared(MediaPlayer mp)。
在实现OnPreparedListener接口的Activity里有: