首先自定義一個繼承自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,不然顯示的方向不對。
如果有可以優化的地方,望各位大俠指導,謝謝。