一、音乐播放在后台也可以,所以应该被定义成一个后台服务程序,在播放服务中包括开始、暂停、停止、继续功能。
private void play() {
// TODO Auto-generated method stub
player.reset();
try {
player.setDataSource("sdcard/bzj.mp3");
player.prepare();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
player.start();
}
private void pause() {
player.pause();
}
private void stop() {
player.stop();
}
private void continuePlay() {
player.start();
}
然后就是启动服务
* 把这几个方法抽取成一个接口MusicInterface
* 定义一个中间人类,继承Binder,实现MusicInterface
* 先start启动MusicService,再bind
Intent intent = new Intent(this, MusicService.class);
startService(intent);
bindService(intent, conn, BIND_AUTO_CREATE);
播放音乐的进度条设置:
获取当前的播放时间和当前音频的最长时间
int currentPosition = player.getCurrentPosition();
int duration = player.getDuration();
* 播放进度需要不停的获取,不停的刷新进度条,使用计时器每500毫秒获取一次播放进度
* 发消息至Handler,把播放进度放进Message对象中,在Handler中更新SeekBar的进度
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
int currentPosition = player.getCurrentPosition();
int duration = player.getDuration();
Message msg = Message.obtain();
//把播放进度存入Message中
Bundle data = new Bundle();
data.putInt("currentPosition", currentPosition);
data.putInt("duration", duration);
msg.setData(data);
MainActivity.handler.sendMessage(msg);
}
}, 5, 500);//每500毫秒刷新一次,延时5毫秒执行。
* 在Activity中定义Handler
static Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
//取出消息携带的数据
Bundle data = msg.getData();
int currentPosition = data.getInt("currentPosition");
int duration = data.getInt("duration");
//设置播放进度
sb.setMax(duration);
sb.setProgress(currentPosition);
};
};
*******拖动改变音乐播放进度
//给sb设置一个拖动侦听
sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
//停止拖动时调用
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
int progress = seekBar.getProgress();
mi.seekTo(progress);
}
//开始拖动时调用
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
//拖动的时候不断调用
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
}
});
***************************************************************************************************************************************************
二、视频播放器
双缓冲技术:内存中有两个画布,A画布显示至屏幕,B画布在内存中绘制下一帧画面,绘制完毕后B显示至屏幕,
* A在内存中继续绘制下一帧画面
* 播放视频也是用MediaPlayer,不过跟音频不同,要设置显示在哪个SurfaceView
* SurfaceView一旦不可见,就会被销毁,一旦可见,就会被创建,销毁时停止播放,再次创建时再开始播放
整个过程:继承SurfaceView并实现SurfaceHolder.Callback接口 ----> SurfaceView.getHolder()获得SurfaceHolder对象 ---->SurfaceHolder.addCallback(callback)添加回调函数---->重写三个方法,实现视频播放和资源释放等。
package com.hasee.video;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
public class MainActivity extends Activity {
MediaPlayer player = null;
int position = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取控件
SurfaceView sv = (SurfaceView)findViewById(R.id.sv_video);
//获取SurfaceView的控制器 holder
SurfaceHolder holder = sv.getHolder();
//实现Callback接口
holder.addCallback(new Callback() {
//重写三个方法
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if(player != null){
position = player.getCurrentPosition();
player.stop();
player.release();
player = null;
}
}
//SurfaceView创建后调用
@Override
public void surfaceCreated(SurfaceHolder holder) {
if(player == null){
player = new MediaPlayer();
player.reset();
try {
player.setDataSource("mnt/sdcard/2.3gp");
//指定视屏播放在哪个surfaceview中
player.setDisplay(holder);
player.prepare();
player.seekTo(position);
player.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
});
}
}