Android调用前后摄像头同时工作实例代码

所属分类: 软件编程 / Android 阅读数: 64
收藏 0 赞 0 分享

硬件环境:小米4

Android版本:6.0

咱们先看效果图:

我把代码贴出来:

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样式和主题之选择器的实例讲解

今天小编就为大家分享一篇关于Android样式和主题之选择器的实例讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
收藏 0 赞 0 分享

Android应用动态修改主题的方法示例

今天小编就为大家分享一篇关于Android应用动态修改主题的方法示例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
收藏 0 赞 0 分享

Flutter 网络请求框架封装详解

这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Flutter倒计时/计时器的实现代码

这篇文章主要介绍了Flutter倒计时/计时器的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Android使用google breakpad捕获分析native cash

这篇文章主要介绍了Android使用google breakpad捕获分析native cash 的相关知识,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

详解Flutter WebView与JS互相调用简易指南

这篇文章主要介绍了详解Flutter WebView与JS互相调用简易指南,分为JS调用Flutter和Flutter调用JS,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Android开发实现ListView和adapter配合显示图片和文字列表功能示例

这篇文章主要介绍了Android开发实现ListView和adapter配合显示图片和文字列表功能,涉及Android使用ListView结合adapter适配器实现图文显示功能相关的布局、解析、权限控制等操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

Android文字基线Baseline算法的使用讲解

今天小编就为大家分享一篇关于Android文字基线Baseline算法的使用讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
收藏 0 赞 0 分享

Flutter自定义实现神奇动效的卡片切换视图的示例代码

这篇文章主要介绍了Flutter自定义实现神奇动效的卡片切换视图的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Android实现自定义滑动刻度尺方法示例

这篇文章主要给大家介绍了关于Android实现自定义滑动刻度尺的相关资料,文中通过示例代码介绍的非常详细,对各位Android开发者们具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
收藏 0 赞 0 分享
查看更多