首先自定义一个继承自SurfaceView并且实现了SurfaceHolder.Callback接口的组件:
public class CameraView extends SurfaceView implements Callback { private SurfaceHolder surfaceHolder; private Camera mCamera; public CameraView(Context context, AttributeSet attrs) { super(context, attrs); } public void init(Camera camera){ surfaceHolder = getHolder(); surfaceHolder.addCallback(this); mCamera = camera; } /** * 初始化SurfaceView时调用一次,另外更改surface或者onpause->onresume时调用 */ @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if(holder.getSurface() == null || mCamera == null){ return; } mCamera.stopPreview(); try { mCamera.setPreviewDisplay(surfaceHolder); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } mCamera.startPreview(); } @Override public void surfaceCreated(SurfaceHolder holder) { if(mCamera == null){ return; } try { mCamera.setPreviewDisplay(surfaceHolder); } catch (IOException e) { e.printStackTrace(); } mCamera.startPreview(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub } }
检查设备是否有摄像头:
private boolean checkCamera(){ return MainActivity.this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA); }
标记前置,后置摄像头,以及当前打开的摄像头,并且首先默认打开前置摄像头,监听Button的click事件,切换摄像头:
public class MainActivity extends Activity { private Button button; private Camera camera; private CameraView cameraView; private static final int FRONT = 1;//前置摄像头标记 private static final int BACK = 2;//后置摄像头标记 private int currentCameraType = -1;//当前打开的摄像头标记 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if(!checkCamera()){ MainActivity.this.finish(); } try { camera = openCamera(FRONT); } catch (Exception e) { e.printStackTrace(); } button = (Button)findViewById(R.id.button); button.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { try { changeCamera(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); cameraView = (CameraView)findViewById(R.id.cameraview); cameraView.init(camera); } /** * @return 摄像头是否存在 */ private boolean checkCamera(){ return MainActivity.this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA); } @SuppressLint("NewApi") private Camera openCamera(int type){ int frontIndex =-1; int backIndex = -1; int cameraCount = Camera.getNumberOfCameras(); CameraInfo info = new CameraInfo(); for(int cameraIndex = 0; cameraIndex<cameraCount; cameraIndex++){ Camera.getCameraInfo(cameraIndex, info); if(info.facing == CameraInfo.CAMERA_FACING_FRONT){ frontIndex = cameraIndex; }else if(info.facing == CameraInfo.CAMERA_FACING_BACK){ backIndex = cameraIndex; } } currentCameraType = type; if(type == FRONT && frontIndex != -1){ return Camera.open(frontIndex); }else if(type == BACK && backIndex != -1){ return Camera.open(backIndex); } return null; } private void changeCamera() throws IOException{ camera.stopPreview(); camera.release(); if(currentCameraType == FRONT){ camera = openCamera(BACK); }else if(currentCameraType == BACK){ camera = openCamera(FRONT); } camera.setPreviewDisplay(cameraView.getHolder()); camera.startPreview(); } }
布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/switchcamera" /> <com.example.cameratest.CameraView android:id="@+id/cameraview" android:layout_below="@id/button" android:layout_width="fill_parent" android:layout_height="fill_parent"/> </RelativeLayout>
当然,首先得申明权限跟软硬件环境:
<uses-permission android:name="android.permission.CAMERA"/> <uses-feature android:name="android.hardware.camera"/>
最好把activity的screenOrientation设置为landscape,不然显示的方向不对。
如果有可以优化的地方,望各位大侠指导,谢谢。
原文:http://www.cnblogs.com/hithlb/p/3543760.html