如何在Android平台上打开“前置摄像头”?


82

更一般而言,如果设备具有多个嵌入式相机,是否有办法特别初始化其中一个?

我在Android参考文档中找不到它:

三星SHW-M100S有两个摄像头。如果没有提到要使用两台相机,那三星会如何...?


Answers:


114
private Camera openFrontFacingCameraGingerbread() {
    int cameraCount = 0;
    Camera cam = null;
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
    cameraCount = Camera.getNumberOfCameras();
    for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
        Camera.getCameraInfo(camIdx, cameraInfo);
        if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            try {
                cam = Camera.open(camIdx);
            } catch (RuntimeException e) {
                Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage());
            }
        }
    }

    return cam;
}

AndroidManifest.xml文件中添加以下权限:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.front" android:required="false" />

注意: Gingerbread(2.3)和更高版本的Android版本提供此功能。


是否有可能以某种方式将其与该Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);技术一起使用以打开现有的相机应用程序?
loeschg 2013年

3
@loeschgIntent以自己的方式处理相机动作。当您SurfaceView用于利用相机功能时,将使用此技术。

这就是我的想法。谢谢!
loeschg 2013年

2
很酷的帖子。我花了一段时间才弄清楚相机的朝向不一定与相机的索引相同。例如,我的平板电脑只有一个摄像头(索引:0),但面向前方(面向索引:1)。因此,使用像Camera.open(CameraInfo.CAMERA_FACING_FRONT)这样的简单代码是没有意义的。
Matthias 2014年

@Matthias同意你的队友。由于我们拥有不同的OEM,因此我们的编程技术会根据需要进行更改。感谢您的强调。

14

Google弃用了所有较早答案的方法(可能是因为这样的麻烦),因为API 21要求您使用Camera 2 API:

该类在API级别21中已弃用。我们建议对新应用程序使用新的android.hardware.camera2 API。

更新的API中,几乎可以完全掌控Android设备的摄像头,并且文档明确建议

String[] getCameraIdList()

然后使用获得的CameraId打开相机:

void openCamera(String cameraId, CameraDevice.StateCallback callback, Handler handler)

99%的前置摄像头id =“ 1”,而后置摄像头id =“ 0” 如下:

不可移动相机的标识符使用以0开头的整数,而可移动相机即使是相同型号,也为每个设备都具有唯一的标识符。

但是,这意味着如果设备情况很少,例如仅1面相机平板电脑,则需要计算您拥有多少个嵌入式相机,并按其重要性(“ 0”)排列相机的顺序。因此CAMERA_FACING_FRONT == 1 CAMERA_FACING_BACK == 0,这意味着后置摄像头更为重要比正面。

我不知道在所有Android设备上识别正面相机的统一方法。简而言之,由于某些原因,设备内的Android OS不能真正找出哪台相机确切在哪里:也许唯一的相机硬编码ID是代表其重要性的整数,或者在某些设备上,无论您转向哪一侧。背部”。

文档https : //developer.android.com/reference/android/hardware/camera2/package-summary.html

明确的示例https : //github.com/googlesamples/android-Camera2Basic


对于较旧的API(不建议使用,因为它在较新的Android版本的现代手机上不起作用,并且传输非常麻烦)。只需使用相同的Integer CameraID(1)来打开前置摄像头,如下所示

cam = Camera.open(1);

如果您信任OpenCV做摄像头部分:

    <org.opencv.android.JavaCameraView
    ../>

对前置摄像头使用以下功能:

        opencv:camera_id="1"

10

从Android 2.1开始,Android在其SDK中仅支持单个摄像头。可能会在将来的Android版本中添加它。


1
此声明也适用于Android 2.2?
ozmank'2

2
@ozmank:是的,直到Android 2.3才添加多摄像机支持。
CommonsWare,2012年

4
public void surfaceCreated(SurfaceHolder holder) {
    try {
        mCamera = Camera.open();
        mCamera.setDisplayOrientation(90);
        mCamera.setPreviewDisplay(holder);

        Camera.Parameters p = mCamera.getParameters();
        p.set("camera-id",2);
        mCamera.setParameters(p);   
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

3
在Galaxy S上工作良好重要的“ camera-id”而不是“ camera_id”
Mahesh 2010年

3
永远不要假设90度会使您正确旋转人像。在许多设备上都不同。
colintheshots 16-3-23的

4

对于API 21(5.0)及更高版本,您可以使用CameraManager API的

try {
    String desiredCameraId = null;
    for(String cameraId : mCameraIDsList) {
        CameraCharacteristics chars =  mCameraManager.getCameraCharacteristics(cameraId);
        List<CameraCharacteristics.Key<?>> keys = chars.getKeys();
        try {
            if(CameraCharacteristics.LENS_FACING_FRONT == chars.get(CameraCharacteristics.LENS_FACING)) {
               // This is the one we want.
               desiredCameraId = cameraId;
               break;
            }
        } catch(IllegalArgumentException e) {
            // This key not implemented, which is a bit of a pain. Either guess - assume the first one
            // is rear, second one is front, or give up.
        }
    }
}

4

打开后置摄像头:-

val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(cameraIntent, REQUEST_CODE_CAMERA)

打开前置摄像头:-

val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
when {
     Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1 && Build.VERSION.SDK_INT < Build.VERSION_CODES.O -> {
         cameraIntent.putExtra("android.intent.extras.CAMERA_FACING", CameraCharacteristics.LENS_FACING_FRONT)  // Tested on API 24 Android version 7.0(Samsung S6)
     }
     Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {
         cameraIntent.putExtra("android.intent.extras.CAMERA_FACING", CameraCharacteristics.LENS_FACING_FRONT) // Tested on API 27 Android version 8.0(Nexus 6P)
         cameraIntent.putExtra("android.intent.extra.USE_FRONT_CAMERA", true)
     }
     else -> cameraIntent.putExtra("android.intent.extras.CAMERA_FACING", 1)  // Tested API 21 Android version 5.0.1(Samsung S4)
}
startActivityForResult(cameraIntent, REQUEST_CODE_CAMERA)

我无法使其适用于API 28及更高版本。另外,在某些设备中(取决于制造商)无法直接打开前置摄像头。



1

build.gradle

 dependencies {
       compile 'com.google.android.gms:play-services-vision:9.4.0+'
    }

设置视图

CameraSourcePreview mPreview = (CameraSourcePreview) findViewById(R.id.preview);

GraphicOverlay mGraphicOverlay = (GraphicOverlay) findViewById(R.id.faceOverlay);

CameraSource mCameraSource = new CameraSource.Builder(context, detector)
                            .setRequestedPreviewSize(640, 480)
                            .setFacing(CameraSource.CAMERA_FACING_FRONT)
                            .setRequestedFps(30.0f)
                            .build();

           mPreview.start(mCameraSource, mGraphicOverlay);

0
Camera camera;   
if (Camera.getNumberOfCameras() >= 2) {

    //if you want to open front facing camera use this line   
    camera = Camera.open(CameraInfo.CAMERA_FACING_FRONT);

    //if you want to use the back facing camera
    camera = Camera.open(CameraInfo.CAMERA_FACING_BACK);                
}

try {
    camera.setPreviewDisplay("your surface holder here");
    camera.startPreview();      
} catch (Exception e) {  
    camera.release();
}

/ *这不是正确的方法,这是针对运行Android 4.0或更旧版本的旧设备的解决方案。可以将其用于测试目的,但不建议用于主要开发。此解决方案只能视为临时解决方案。但是此解决方案已帮助了很多人,因此我不打算删除此答案* /


7
我不认为这是有记录的用法。open(int id)接受id,而不是摄影机位置
2014年

13
请删除此误导性答案
Alex Cohn 2014年

13
@AmalanDhananjayan:例如,请参见上面@Matthias 的评论:…花了我一段时间才能弄清楚摄像头朝向与摄像头索引不一定相同。例如,我的平板电脑只有一个摄像头(索引:0),但面向前方(面向索引:1)。因此,使用像Camera.open(CameraInfo.CAMERA_FACING_FRONT)这样的简单代码是没有意义的。
亚历克斯·科恩

5
这是balderdash。甚至不要尝试使用它。
亚当

4
这太可怕了。永远不要这样做。这个答案应该被禁止。Camera.open()接受相机ID,而不是朝向的相机序号!这在少数设备上都无法实现,只能通过纯粹的运气来解决。
colintheshots 16-3-23的
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.