Android开发之路优秀案例Android知识

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

2017-07-06  本文已影响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中注册了

上一篇下一篇

猜你喜欢

热点阅读