zoukankan      html  css  js  c++  java
  • android实现前置后置摄像头相互切换

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

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

  • 相关阅读:
    【UOJ Round #3】
    【UOJ Round #1】
    【BZOJ】【3673】可持久化并查集 & 【3674】可持久化并查集加强版
    【ContestHunter】【弱省胡策】【Round7】
    【BZOJ】【3211】花神游历各国
    【BZOJ】【4146】 【AMPPZ2014】Divisors
    【BZOJ】【3931】【CQOI2015】网络吞吐量
    【BZOJ】【3697】采药人的路径&【3127】【USACO2013 Open】Yin and Yang
    【BZOJ】【3930】【CQOI2015】选数
    【ContestHunter】【弱省胡策】【Round6】
  • 原文地址:https://www.cnblogs.com/hithlb/p/3543760.html
Copyright © 2011-2022 走看看