同样,在开始使用摄像头之前,还需要创建某种类型的Surface(表面),使得Camera应用程序能够在其绘制取景器(viewfinder)或预览图像。Surface是Android中的一个抽象类,表示绘制图形或图像的位置。提供一个绘图Surface的最简单的方法就是使用SurfaceView类。SurfaceView是在标准视图中提供Surface的具体类。
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="match_parent" 3 android:layout_height="match_parent" 4 android:orientation="vertical" 5 > 6 <SurfaceView 7 android:id="@+id/CameraView" 8 android:layout_width="match_parent" 9 android:layout_height="match_parent" 10 /> 11 </LinearLayout>
为了在代码中实现通过Camera此SurfaceView,需要添加一个SurfaceHolder类。SurfaceHolder类可以作为Surface上的一个监控器,并且通过回调提供接口,从而让我们知道什么时候创建、销毁或更改Surface。同时,SurfaceView类还提供了一个getHolder方法,用于获得一个对应其Surface的SurfaceHolder对象。
以下代码片段。其访问在布局XML中声明的SurfaceView,并从中获得一个SurfaceHolder。同时,它还设置该Surface是一个“推送”类型的Surface,这意味着在Surface本身的外部维持绘图缓冲区。在这种情况下,该缓冲区有Camera类管理。“推送”类型的Surface是Camera预览所需的Surface。
1 cameraView=(SurfaceView) findViewById(R.id.CameraView); 2 surfaceHolder=cameraView.getHolder(); 3 surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
另外,我们可能希望在活动中实现SurfaceHolder.Callback,从而使得在创建、修改及销毁该Surface时活动将会获得通知。为了实现回调,需要添加一下方法。
1 @Override 2 public void surfaceCreated(SurfaceHolder holder) { 3 4 } 5 6 @Override 7 public void surfaceChanged(SurfaceHolder holder, int format, int width, 8 int height) { 9 10 } 11 12 @Override 13 public void surfaceDestroyed(SurfaceHolder holder) { 14 15 }
最后,需要告诉SurfaceHolder使用该活动作为回调处理程序。
1 surfaceHolder.addCallback(this);
现在活动看起来如下所示:
1 package com.nthm.androidtest; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.SurfaceHolder; 6 import android.view.SurfaceView; 7 8 public class SnapShot extends Activity implements SurfaceHolder.Callback { 9 private SurfaceView cameraView; 10 private SurfaceHolder surfaceHolder; 11 12 @Override 13 protected void onCreate(Bundle savedInstanceState) { 14 super.onCreate(savedInstanceState); 15 setContentView(R.layout.snapshot); 16 cameraView=(SurfaceView) findViewById(R.id.CameraView); 17 surfaceHolder=cameraView.getHolder(); 18 surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 19 surfaceHolder.addCallback(this); 20 } 21 22 @Override 23 public void surfaceCreated(SurfaceHolder holder) { 24 25 } 26 27 @Override 28 public void surfaceChanged(SurfaceHolder holder, int format, int width, 29 int height) { 30 31 } 32 33 @Override 34 public void surfaceDestroyed(SurfaceHolder holder) { 35 36 } 37 }