85

更一般地说,如果设备有多个嵌入式摄像头,有没有办法特别初始化其中一个?

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

三星 SHW-M100S 有两个摄像头。如果没有提到使用两台相机,知道三星是如何做到的......?

4

10 回答 10

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) 和 Up Android 版本中可用。

于 2011-01-22T12:36:50.977 回答
14

All older answers' methods are deprecated by Google (supposedly because of troubles like this), since API 21 you need to use the Camera 2 API:

This class was deprecated in API level 21. We recommend using the new android.hardware.camera2 API for new applications.

In the newer API you have almost complete power over the Android device camera and documentation explicitly advice to

String[] getCameraIdList()

and then use obtained CameraId to open the camera:

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

99% of the frontal cameras have id = "1", and the back camera id = "0" according to this:

Non-removable cameras use integers starting at 0 for their identifiers, while removable cameras have a unique identifier for each individual device, even if they are the same model.

However, this means if device situation is rare like just 1-frontal -camera tablet you need to count how many embedded cameras you have, and place the order of the camera by its importance ("0"). So CAMERA_FACING_FRONT == 1 CAMERA_FACING_BACK == 0, which implies that the back camera is more important than frontal.

I don't know about a uniform method to identify the frontal camera on all Android devices. Simply said, the Android OS inside the device can't really find out which camera is exactly where for some reasons: maybe the only camera hardcoded id is an integer representing its importance or maybe on some devices whichever side you turn will be .. "back".

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

Explicit Examples: https://github.com/googlesamples/android-Camera2Basic


For the older API (it is not recommended, because it will not work on modern phones newer Android version and transfer is a pain-in-the-arse). Just use the same Integer CameraID (1) to open frontal camera like in this answer:

cam = Camera.open(1);

If you trust OpenCV to do the camera part:

Inside

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

use the following for the frontal camera:

        opencv:camera_id="1"
于 2016-02-26T09:35:19.110 回答
10

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

于 2010-05-07T11:56:09.313 回答
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();
    }
}
于 2010-11-09T14:56:38.090 回答
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.
        }
    }
}
于 2017-02-10T11:25:56.060 回答
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 及更高版本。此外,某些设备无法直接打开前置摄像头(取决于制造商)。

于 2019-09-10T13:34:24.570 回答
2

随着Android 2.3 (Gingerbread) 的发布,您现在可以使用android.hardware.Camera该类来获取摄像头的数量、有关特定摄像头的信息,并获取对特定Camera. 在此处查看新的CameraAPI 。

于 2010-12-06T16:33:29.143 回答
1

构建.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);
于 2017-08-10T20:05:52.267 回答
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 或更早版本的旧设备的解决方案。这可以用于测试目的,但不推荐用于主要开发。此解决方案只能被视为临时解决方案。但是这个解决方案帮助了很多人,所以我不打算删除这个答案*/

于 2013-03-28T11:59:10.327 回答
0

我发现这很好用。

fun frontCamera(context: Context): Int {
    val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
    return cameraManager.cameraIdList
        .find { id ->
            cameraManager.getCameraCharacteristics(id)[LENS_FACING] == LENS_FACING_FRONT
        }?.toInt() ?: 0
}
于 2021-10-26T10:11:59.897 回答