Как открыть "переднюю камеру" на платформе Android?

В общем случае, если устройство имеет более одной встроенной камеры, есть ли способ инициализировать один из них в частности?

Я не нашел его в справочной документации Android:

Samsung SHW-M100S имеет две камеры. Если нет ссылки на использование двух камер, любая идея, как Samsung сделал...?

Ответ 1

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 версии.

Ответ 2

Все более старые методы ответов устарели в 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", а у задней камеры = 0" в соответствии с этим:

Несъемные камеры используют целые числа, начинающиеся с 0 для их идентификаторы, в то время как съемные камеры имеют уникальный идентификатор для каждого индивидуальное устройство, даже если они одной модели.

Тем не менее,, это означает, что если ситуация с устройством является редкой, например, с 1-фронтальным планшетом -camera, вам необходимо подсчитать, сколько встроенных камер у вас есть, и определить порядок расположения камер по важности ( 0"). Итак, CAMERA_FACING_FRONT == 1 CAMERA_FACING_BACK == 0, что означает, что задняя камера важнее important, чем фронтальная.

Я не знаю о едином методе для идентификации фронтальной камеры на всех устройствах Android. Проще говоря, ОС Android внутри устройства не может точно определить, где именно находится камера, по ряду причин: возможно, единственным жестко заданным идентификатором камеры является целое число, представляющее ее важность, или, возможно, на некоторых устройствах, какой бы стороной вы ни повернулись... " назад".

Документация: 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"

Ответ 3

Начиная с Android 2.1, Android поддерживает только одну камеру в SDK. Вполне вероятно, что это будет добавлено в будущую версию Android.

Ответ 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();
    }
}

Ответ 5

Для API 21 (5.0) и более поздних версий вы можете использовать API CameraManager

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.
        }
    }
}

Ответ 6

С выпуском Android 2.3 (Gingerbread) теперь вы можете использовать класс android.hardware.Camera для получения количества камер, информацию о конкретной камере и получить ссылку на конкретный Camera. Ознакомьтесь с новыми Camera API здесь.

Ответ 7

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);

Ответ 8

Чтобы открыть заднюю камеру: -

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 и выше. Кроме того, прямое открытие передней камеры на некоторых устройствах невозможно (зависит от производителя).

Ответ 9

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 или старше. Это может использоваться для целей тестирования, но не рекомендуется для основной разработки. Это решение можно рассматривать только как временное решение. Но это решение помогло многим, поэтому я не собираюсь удалять этот ответ */