1.要使用MediaPlayer播放视频,需要编写一个可以用于视频显示的空间,而这块空间要求可以快速进行GUI更新,而且可以在渲染代码时对GUI进行无阻塞的渲染,要实现该功能需要android.view.SurfaceView组件。SurfaceView组件封装了一个Surface对象,使用Surface可以完成对后台线程的控制,对于视频、3D图形等需要快速更新或者高帧率的对象有很大用处。
在SurfaceView类中,getHolder()方法最常用,该方法返回一个android.view.SurfaceHolder接口的实例化对象,使用SurfaceHolder接口可以控制显示的大小、像素等。
2.播放sdcard中的视频文件:
public class MyVideoPlayerDemo extends Activity {
private ImageButton play = null ;
private ImageButton stop = null ;
private MediaPlayer media = null ;
private SurfaceView surfaceView = null ;
private SurfaceHolder surfaceHolder = null ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.main);
this.play = (ImageButton) super.findViewById(R.id.play) ;
this.stop = (ImageButton) super.findViewById(R.id.stop) ;
this.surfaceView = (SurfaceView) super.findViewById(R.id.surfaceView) ;
this.surfaceHolder = this.surfaceView.getHolder() ;//取得SurfaceHolder
//设置SurfaceView的类型
this.surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
this.media = new MediaPlayer() ;//创建MediaPlayer对象
try {
this.media.setDataSource("/sdcard/mldn.3gp") ; //设置播放文件的路径
} catch (Exception e) {
e.printStackTrace();
}
this.play.setOnClickListener(new PlayOnClickListenerImpl()) ;
this.stop.setOnClickListener(new StopOnClickListenerImpl()) ;
}
private class PlayOnClickListenerImpl implements OnClickListener {
@Override
public void onClick(View v) {
//设置音频类型
MyVideoPlayerDemo.this.media.setAudioStreamType(AudioManager.STREAM_MUSIC) ;
//设置显示区域
MyVideoPlayerDemo.this.media.setDisplay(MyVideoPlayerDemo.this.surfaceHolder) ;
try {
MyVideoPlayerDemo.this.media.prepare() ;//预备状态
} catch (Exception e) {
}
MyVideoPlayerDemo.this.media.start() ;//播放视频
}
}
private class StopOnClickListenerImpl implements OnClickListener {
@Override
public void onClick(View v) {
MyVideoPlayerDemo.this.media.stop() ;//停止播放
}
}
}
使用摄像头拍照
1.想实现拍照功能,需要手工实现android.view.SurfaceHolder.Callback操作接口。调用摄像头的操作类android.hardware.Camera,此类主要负责完成拍照的参数设置及保存。
2.捕获图像:
public class MyCameraDemo extends Activity {
private SurfaceView surface = null ;
private Button but = null ;
private SurfaceHolder holder = null ;
private Camera cam = null ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.main);
this.but = (Button) super.findViewById(R.id.but) ;
this.surface = (SurfaceView) super.findViewById(R.id.surface) ;
this.holder = this.surface.getHolder() ;
this.holder.addCallback(new MySurfaceViewCallback()) ;
this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS) ;
this.holder.setFixedSize(800, 480);
this.but.setOnClickListener(new OnClickListenerImpl()) ;
}
private class OnClickListenerImpl implements OnClickListener {
@Override
public void onClick(View v) {
}
}
private class MySurfaceViewCallback implements SurfaceHolder.Callback {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
MyCameraDemo.this.cam = Camera.open(0) ; // 取得第一个摄像头
WindowManager manager = (WindowManager) MyCameraDemo.this
.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay() ;
Parameters param = MyCameraDemo.this.cam.getParameters() ;
param.setPreviewSize(display.getWidth(), display.getHeight()) ;
param.setPreviewFrameRate(5) ; // 一秒5帧
param.setPictureFormat(PixelFormat.JPEG) ; // 图片形式
param.set("jpen-quality", 85) ;
MyCameraDemo.this.cam.setParameters(param) ;
try {
MyCameraDemo.this.cam.setPreviewDisplay(MyCameraDemo.this.holder) ;
} catch (IOException e) {
}
MyCameraDemo.this.cam.startPreview() ; // 进行预览
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
}
3.实现拍照
public class MyCameraDemo extends Activity {
private SurfaceView surface = null ;//主要用于取得SurfaceHolder对象
private Button but = null ;
private SurfaceHolder holder = null ;//主要用来设置图片的类型、分辨率等参数以及//指定SurfaceHolder.Callback
private Camera cam = null ;//负责具体的拍照操作
private boolean previewRunning = true ;//保存现在是否是预览状态
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.main);
super.requestWindowFeature(Window.FEATURE_NO_TITLE);//不显示标题
super.getWindow.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏显示
super.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//高亮显示
this.but = (Button) super.findViewById(R.id.but) ;
this.surface = (SurfaceView) super.findViewById(R.id.surface) ;
this.holder = this.surface.getHolder() ;//调用Holder
this.holder.addCallback(new MySurfaceViewCallback()) ;//加入回调
this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS) ;//设置缓冲类型
this.holder.setFixedSize(500, 350);//设置分辨率
this.but.setOnClickListener(new OnClickListenerImpl()) ;
}
private class OnClickListenerImpl implements OnClickListener {
@Override
public void onClick(View v) {
if(MyCameraDemo.this.cam != null) {//存在Camera对象
MyCameraDemo.this.cam.autoFocus(new AutoFocusCallbackImpl()) ;//自动对焦
}
}
}
//接口SurfaceHolder.Callback被用来接收摄像头预览界面变化的信息
private class MySurfaceViewCallback implements SurfaceHolder.Callback {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {//当预览界面的格式和大小发生改变时,该方法被调用
}
@Override
public void surfaceCreated(SurfaceHolder holder) {//初次实例化预览界面调用
MyCameraDemo.this.cam = Camera.open(0) ; // 取得第一个摄像头
WindowManager manager = (WindowManager) MyCameraDemo.this
.getSystemService(Context.WINDOW_SERVICE);//取得服务
Display display = manager.getDefaultDisplay() ;//取得Display对象
Parameters param = MyCameraDemo.this.cam.getParameters() ;//取得相机参数
param.setPreviewSize(display.getWidth(), display.getHeight()) ;//设置预览大小
param.setPreviewFrameRate(5) ; // 一秒5帧
param.setPictureFormat(PixelFormat.JPEG) ; // 图片形式
param.set("jpen-quality", 80) ;//设置图片质量,最高为100
MyCameraDemo.this.cam.setParameters(param) ;//设置参数
try {//通过SurfaceView显示
MyCameraDemo.this.cam.setPreviewDisplay(MyCameraDemo.this.holder) ;
} catch (IOException e) {
}
MyCameraDemo.this.cam.startPreview() ; // 进行预览
MyCameraDemo.this.previewRunning = true ; // 修改预览标记,已经开始预览
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {//当预览界面被关闭时方法被调用
if(MyCameraDemo.this.cam != null) {
if(MyCameraDemo.this.previewRunning) {//如果正在预览
MyCameraDemo.this.cam.stopPreview() ; // 停止预览
MyCameraDemo.this.previewRunning = false ;//修改标记
}
//摄像头只能被一个Activity程序使用,所有要释放摄像头
MyCameraDemo.this.cam.release() ;//释放摄像头
}
}
}
private class AutoFocusCallbackImpl implements AutoFocusCallback {
@Override
public void onAutoFocus(boolean success, Camera camera) {
if(success) { // 对焦成功
MyCameraDemo.this.cam.takePicture(sc, pc, jpgcall) ;//获取图片
MyCameraDemo.this.cam.stopPreview();//停止预览
}
}
}
private PictureCallback jpgcall = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) { // 保存图片的操作
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
String fileName = Environment.getExternalStorageDirectory()
.toString()
+ File.separator
+ "mldnphoto"
+ File.separator
+ "MLDN_" + System.currentTimeMillis() + ".jpg";//输出文件名称
File file = new File(fileName) ;//定义File对象
if (!file.getParentFile().exists()) {//父文件夹不存在
file.getParentFile().mkdirs() ; // 创建文件夹
}
try {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)) ;//使用字节缓存流
bmp.compress(Bitmap.CompressFormat.JPEG, 80, bos) ; // 向缓冲区之中压缩图片
bos.flush() ;//清空缓存
bos.close() ;//关闭
Toast.makeText(MyCameraDemo.this,
"拍照成功,照片已保存在" + fileName + "文件之中!", Toast.LENGTH_SHORT)
.show();//显示Toast
} catch (Exception e) {
Toast.makeText(MyCameraDemo.this,
"拍照失败!", Toast.LENGTH_SHORT)
.show();
}
MyCameraDemo.this.cam.stopPreview() ;//停止预览
MyCameraDemo.this.cam.startPreview() ;//开始预览
}
} ;
private ShutterCallback sc = new ShutterCallback(){
@Override
public void onShutter() {
// 按下快门之后进行的操作
}
} ;
private PictureCallback pc = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
//保存的源图片数据
}
} ;
}
配置权限文件:
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />