|--效果图
|--依赖3个对象
MediaPlayer:实现音乐播放,暂停,缓冲。
SeekBar:滑动的进度条。
java.util.Timer:定时器,时时更新进度条。
|--main.xml样式文件
<span style="font-size:14px;"> <TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<EditText
android:id="@+id/mediaFileName"
android:layout_width="match_parent"
android:text="gangstabop.mp3"
android:layout_height="wrap_content" >
<requestFocus />
</EditText>
<LinearLayout
android:id="@+id/linearButton"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/playButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/stop" />
<SeekBar
android:id="@+id/playSeekBar"
android:layout_width="140px"
android:layout_height="wrap_content"
android:layout_marginLeft="3px"
android:layout_marginTop="5px" />
<Button
android:id="@+id/replayButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3px"
android:text="@string/replay" />
</LinearLayout></span><span style="font-size: 24px;">
</span>
|--Activity实现代码
<span style="font-size:14px;">/**
* @CreateDate 2015-2-3
* @Author hubiao
* @Title 音乐播放器
*/
public class MediaActivity extends Activity {
private MediaPlayer mediaPlayer;//媒体播放器
private Button playButton;
private Button replayButton ;
private boolean isCellPlay;/*在挂断电话的时候,用于判断是否为是来电时中断*/
private boolean isSeekBarChanging;//互斥变量,防止进度条与定时器冲突。
private int currentPosition;//当前音乐播放的进度
private SeekBar seekBar;
private Timer timer;
private static final String TAG = "MediaActivity";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//实例化媒体播放器
mediaPlayer = new MediaPlayer();
//监听滚动条事件
seekBar = (SeekBar) findViewById(R.id.playSeekBar);
seekBar.setOnSeekBarChangeListener(new MySeekBar());
// 监听[播放或暂停]事件
playButton= (Button) findViewById(R.id.playButton);
playButton.setOnClickListener(new PalyListener());
//监听[重播]事件
replayButton= (Button) findViewById(R.id.replayButton);
replayButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mediaPlayer.reset();
currentPosition = 0;
play();
}
});
//监听来电事件
TelephonyManager phoneyMana = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
phoneyMana.listen(new myPhoneStateListener(),PhoneStateListener.LISTEN_CALL_STATE);
}
/*销毁时释资源*/
@Override
protected void onDestroy() {
mediaPlayer.release();
timer.cancel();
timer = null;
mediaPlayer = null;
super.onDestroy();
}
/*播放或暂停事件处理*/
private class PalyListener implements OnClickListener {
public void onClick(View v) {
if(playButton.getText().toString().equals("播放"))
{
currentPosition = mediaPlayer.getCurrentPosition();//记录播放的位置
mediaPlayer.stop();//暂停状态
playButton.setText(R.string.stop);
timer.purge();//移除所有任务;
}
else{
mediaPlayer.reset();
play();
}
}
}
/*播放处理*/
private void play() {
File media = new File("/mnt/sdcard/files/","bewithyou.mp3");//由于是练习,就把mp3名称固定了
Log.i(TAG, media.getAbsolutePath());
if(media.exists())
{
try {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);//设置音频类型
mediaPlayer.setDataSource(media.getAbsolutePath());//设置mp3数据源
mediaPlayer.prepareAsync();//数据缓冲
/*监听缓存 事件,在缓冲完毕后,开始播放*/
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mp.start();
mp.seekTo(currentPosition);
playButton.setText(R.string.play);
seekBar.setMax(mediaPlayer.getDuration());
}
});
//监听播放时回调函数
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if(!isSeekBarChanging){
seekBar.setProgress(mediaPlayer.getCurrentPosition());
}
}
},0,50);
} catch (Exception e) {
Toast.makeText(getApplicationContext(), R.string.playError, Toast.LENGTH_LONG).show();
e.printStackTrace();
System.out.println(e);
}
}
else{
Toast.makeText(getApplicationContext(), R.string.fileError, Toast.LENGTH_LONG).show();
}
}
/*来电事件处理*/
private class myPhoneStateListener extends PhoneStateListener
{
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING://来电,应当停止音乐
if(mediaPlayer.isPlaying() && playButton.getText().toString().equals("播放")){
currentPosition = mediaPlayer.getCurrentPosition();//记录播放的位置
mediaPlayer.stop();
isCellPlay = true;//标记这是属于来电时暂停的标记
playButton.setText(R.string.stop);
timer.purge();//移除定时器任务;
}
break;
case TelephonyManager.CALL_STATE_IDLE://无电话状态
if(isCellPlay){
isCellPlay = false;
mediaPlayer.reset();
play();
}
break;
}
}
}
/*进度条处理*/
public class MySeekBar implements OnSeekBarChangeListener{
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
}
/*滚动时,应当暂停后台定时器*/
public void onStartTrackingTouch(SeekBar seekBar) {
isSeekBarChanging = true;
}
/*滑动结束后,重新设置值*/
public void onStopTrackingTouch(SeekBar seekBar) {
isSeekBarChanging = false;
mediaPlayer.seekTo(seekBar.getProgress());
}
}
}</span>
|--补充
1:如果mp3在sd中,如播放失败,是否申请sd访问权限或mp3文件是否存在。
2:MediaPlayer对有个别的音频好像不太支持,如果路径正确,权限具备还无法播放,就考虑下音频问题。
3:本案例用到的权限。
<!-- 申请SD卡写入权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--申请SD卡创建与权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- 拦截号码权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>