美文网首页Android开发之路优秀案例Android知识
Android调用前后摄像头同时工作

Android调用前后摄像头同时工作

作者: 大胡子的机器人 | 来源:发表于2017-07-06 16:02 被阅读578次

    硬件环境:小米4
    Android版本:6.0

    咱们先看效果图:

    Paste_Image.png

    我把代码贴出来:

    AndroidMainfest.xml文件(需要新增camera权限):

       <uses-permission android:name="android.permission.CAMERA" />
    

    activity_main.xml文件:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.bihu.qdemopush.MainActivity">
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:orientation="horizontal">
        <SurfaceView
            android:id="@+id/surfaceview1"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="fill_parent" />
        <SurfaceView
            android:id="@+id/surfaceview2"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_marginLeft="5dp"
            android:layout_height="fill_parent" />
    </LinearLayout>
    </LinearLayout>
    

    MainActivity.java文件:主要是对2个surfaceView的显示渲染

    public class MainActivity extends AppCompatActivity {
    
    SurfaceView surfaceview1, surfaceview2;
    SurfaceHolder surfaceholder1, surfaceholder2;
    String TAG = "MainActivity";
    private Camera camera1 = null, camera2;
    Camera.Parameters parameters;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        surfaceview1 = (SurfaceView) findViewById(R.id.surfaceview1);
        surfaceview2 = (SurfaceView) findViewById(R.id.surfaceview2);
        surfaceholder1 = surfaceview1.getHolder();
        surfaceholder1.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        surfaceholder1.addCallback(new surfaceholderCallbackBack());
    
        surfaceholder2 = surfaceview2.getHolder();
        surfaceholder2.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        surfaceholder2.addCallback(new surfaceholderCallbackFont());
    }
    
    @Override
    protected void onDestroy() {
        Log.e(TAG, "onDestroy");
        super.onDestroy();
    }
    
    /**
     * 后置摄像头回调
     */
    class surfaceholderCallbackBack implements SurfaceHolder.Callback {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            // 获取camera对象
            int cameraCount = Camera.getNumberOfCameras();
            if (cameraCount > 0) {
                camera1 = Camera.open(0);
                try {
                    // 设置预览监听
                    camera1.setPreviewDisplay(holder);
                    Camera.Parameters parameters = camera1.getParameters();
    
                    if (MainActivity.this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
                        parameters.set("orientation", "portrait");
                        camera1.setDisplayOrientation(90);
                        parameters.setRotation(90);
                    } else {
                        parameters.set("orientation", "landscape");
                        camera1.setDisplayOrientation(0);
                        parameters.setRotation(0);
                    }
                    camera1.setParameters(parameters);
                    // 启动摄像头预览
                    camera1.startPreview();
                    System.out.println("camera.startpreview");
    
                } catch (IOException e) {
                    e.printStackTrace();
                    camera1.release();
                    System.out.println("camera.release");
                }
            }
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            camera1.autoFocus(new Camera.AutoFocusCallback() {
                @Override
                public void onAutoFocus(boolean success, Camera camera) {
                    if (success) {
                        initCamera();// 实现相机的参数初始化
                        camera.cancelAutoFocus();// 只有加上了这一句,才会自动对焦。
                    }
                }
            });
    
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
    
        }
    
        // 相机参数的初始化设置
        private void initCamera() {
            parameters = camera1.getParameters();
            parameters.setPictureFormat(PixelFormat.JPEG);
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);// 1连续对焦
            setDispaly(parameters, camera1);
            camera1.setParameters(parameters);
            camera1.startPreview();
            camera1.cancelAutoFocus();// 2如果要实现连续的自动对焦,这一句必须加上
        }
    
        // 控制图像的正确显示方向
        private void setDispaly(Camera.Parameters parameters, Camera camera) {
            if (Integer.parseInt(Build.VERSION.SDK) >= 8) {
                setDisplayOrientation(camera, 90);
            } else {
                parameters.setRotation(90);
            }
    
        }
    
        // 实现的图像的正确显示
        private void setDisplayOrientation(Camera camera, int i) {
            Method downPolymorphic;
            try {
                downPolymorphic = camera.getClass().getMethod("setDisplayOrientation", new Class[]{int.class});
                if (downPolymorphic != null) {
                    downPolymorphic.invoke(camera, new Object[]{i});
                }
            } catch (Exception e) {
                Log.e("Came_e", "图像出错");
            }
        }
    }
    
    class surfaceholderCallbackFont implements SurfaceHolder.Callback {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            // 获取camera对象
            int cameraCount = Camera.getNumberOfCameras();
            if (cameraCount == 2) {
                camera2 = Camera.open(1);
            }
            try {
                // 设置预览监听
                camera2.setPreviewDisplay(holder);
                Camera.Parameters parameters = camera2.getParameters();
    
                if (MainActivity.this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
                    parameters.set("orientation", "portrait");
                    camera2.setDisplayOrientation(90);
                    parameters.setRotation(90);
                } else {
                    parameters.set("orientation", "landscape");
                    camera2.setDisplayOrientation(0);
                    parameters.setRotation(0);
                }
                camera2.setParameters(parameters);
                // 启动摄像头预览
                camera2.startPreview();
                System.out.println("camera.startpreview");
    
            } catch (IOException e) {
                e.printStackTrace();
                camera2.release();
                System.out.println("camera.release");
            }
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            camera2.autoFocus(new Camera.AutoFocusCallback() {
                @Override
                public void onAutoFocus(boolean success, Camera camera) {
                    if (success) {
                        parameters = camera2.getParameters();
                        parameters.setPictureFormat(PixelFormat.JPEG);
                        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);// 1连续对焦
                        setDispaly(parameters, camera2);
                        camera2.setParameters(parameters);
                        camera2.startPreview();
                        camera2.cancelAutoFocus();// 2如果要实现连续的自动对焦,这一句必须加上
                        camera.cancelAutoFocus();// 只有加上了这一句,才会自动对焦。
                    }
                }
            });
    
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
    
        }
    
        // 控制图像的正确显示方向
        private void setDispaly(Camera.Parameters parameters, Camera camera) {
            if (Integer.parseInt(Build.VERSION.SDK) >= 8) {
                setDisplayOrientation(camera, 90);
            } else {
                parameters.setRotation(90);
            }
    
        }
    
        // 实现的图像的正确显示
        private void setDisplayOrientation(Camera camera, int i) {
            Method downPolymorphic;
            try {
                downPolymorphic = camera.getClass().getMethod("setDisplayOrientation", new Class[]{int.class});
                if (downPolymorphic != null) {
                    downPolymorphic.invoke(camera, new Object[]{i});
                }
            } catch (Exception e) {
                Log.e("Came_e", "图像出错");
            }
        }
    }
    }
    

    可能出现的问题:
    1、没有权限,需要手动打开,代码里由于追求简便,没有主动申请,只在mainfest中注册了

    相关文章

      网友评论

      • 万年小学生:支持前后两个摄像头,是从Android 6.0开始的吗
        大胡子的机器人:@aimaile 貌似是摄像头要么没权限要么摄像头被占用,要么摄像头损坏了
        aimaile:测试,打开报错
        FATAL EXCEPTION: main
        Process: uvc.aimaile.cn.myapplication, PID: 11536
        java.lang.RuntimeException: Fail to connect to camera service
        at android.hardware.Camera.native_setup(Native Method)
        at android.hardware.Camera.<init>(Camera.java:350)
        at android.hardware.Camera.open(Camera.java:309)
        at uvc.aimaile.cn.myapplication.MainActivity$surfaceholderCallbackFont.surfaceCreated(MainActivity.java:144)
        大胡子的机器人:@万年小学生 这个不确定哦

      本文标题:Android调用前后摄像头同时工作

      本文链接:https://www.haomeiwen.com/subject/xpwhhxtx.html