首先自定义一个继承自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){            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,不然显示的方向不对。

如果有可以优化的地方,望各位大侠指导,谢谢。


更多相关文章

  1. Android 相机2之常用工具代码(预览方向、预览尺寸、全屏显示、分
  2. [置顶] Android防火墙+流量统计代码
  3. Android里用代码设置View的相关属性
  4. Android自动测试代码
  5. Android Audio代码分析18 - setSampleRate函数
  6. Android Audio代码分析22 - AudioEffect::getEnabled函数
  7. 转:在Eclipse中查看Android SDK的源代码

随机推荐

  1. android中的menu和子menu小结
  2. Android(安卓)测试工具集02
  3. Android中使用ALSA声卡
  4. Android(安卓)深入解析用户界面(四)
  5. android 在配置文件中指定上级activity
  6. android notes(1)
  7. Android(安卓)结束进程的方法
  8. 一张图带你掌握Android(安卓)Q上InputDis
  9. android 去掉应用程序自带的黑色的头部横
  10. Android错误信息汇总