¿Cómo abro la “cámara frontal” en la plataforma Android?

82

De manera más general, si un dispositivo tiene más de una cámara incorporada, ¿hay alguna forma de inicializar una de ellas en particular?

No lo encontré en la documentación de referencia de Android:

Samsung SHW-M100S tiene dos cámaras. Si no hay referencia para usar dos cámaras, ¿alguna idea de cómo lo hizo Samsung ...?

Sol
fuente
posible duplicado de Cómo usar la cámara frontal en Samsung Galaxy S
Esteban Küber

Respuestas:

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

Agregue los siguientes permisos en el AndroidManifest.xmlarchivo:

<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" />

Nota: esta función está disponible en Gingerbread (2.3) y en la versión de Android Up.

Crisoforo Gaspar
fuente
¿Es posible usar esto de alguna manera con la Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);técnica para abrir la aplicación de cámara existente?
Loeschg
3
@loeschg Intentmaneja la acción de la cámara a su manera. Esta técnica se utiliza cuando se utiliza SurfaceViewpara explotar la funcionalidad de la cámara.
eso es lo que me imaginé. ¡Gracias!
loeschg
2
Muy buena publicación. Me tomó un tiempo darme cuenta de que la orientación de la cámara no es necesariamente la misma que el índice de la cámara. Por ejemplo, mi tableta tiene solo una cámara (índice: 0) pero orientada hacia el frente (índice orientado: 1). Por lo tanto, usar un código simple como Camera.open (CameraInfo.CAMERA_FACING_FRONT) no tiene sentido.
Matthias
@Matthias De acuerdo contigo, compañero. Como tenemos diferentes OEM, nuestra técnica de programación cambia según nuestras necesidades. Gracias por destacar.
14

Todos los métodos de respuestas anteriores están obsoletos por Google (supuestamente debido a problemas como este), ya que API 21 necesita usar la API de Camera 2:

Esta clase quedó obsoleta en el nivel de API 21. Recomendamos utilizar la nueva API android.hardware.camera2 para nuevas aplicaciones.

En la API más nueva , tiene un poder casi completo sobre la cámara del dispositivo Android y la documentación se aconseja explícitamente a

String[] getCameraIdList()

y luego use CameraId obtenido para abrir la cámara:

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

El 99% de las cámaras frontales tienen id = "1", y la cámara trasera id = "0" según esto:

Las cámaras no extraíbles utilizan números enteros que comienzan en 0 para sus identificadores, mientras que las cámaras extraíbles tienen un identificador único para cada dispositivo individual, incluso si son del mismo modelo.

Sin embargo , esto significa que si la situación del dispositivo es poco común, como una tableta con una cámara frontal, debe contar cuántas cámaras integradas tiene y colocar el orden de la cámara por su importancia ("0"). Entonces CAMERA_FACING_FRONT == 1 CAMERA_FACING_BACK == 0, lo que implica que la cámara trasera es más importante que la frontal.

No conozco un método uniforme para identificar la cámara frontal en todos los dispositivos Android. En pocas palabras, el sistema operativo Android dentro del dispositivo no puede saber realmente qué cámara está exactamente donde por algunas razones: tal vez la única identificación codificada de la cámara sea un número entero que represente su importancia o tal vez en algunos dispositivos, el lado al que mire será ... " espalda".

Documentación : https://developer.android.com/reference/android/hardware/camera2/package-summary.html

Ejemplos explícitos : https://github.com/googlesamples/android-Camera2Basic


Para la API anterior (no se recomienda, porque no funcionará en teléfonos modernos con la versión más reciente de Android y la transferencia es una molestia). Simplemente use el mismo ID de cámara entero (1) para abrir la cámara frontal como en esta respuesta :

cam = Camera.open(1);

Si confía en OpenCV para hacer la parte de la cámara:

Dentro

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

utilice lo siguiente para la cámara frontal:

        opencv:camera_id="1"
iantonuk
fuente
10

A partir de Android 2.1, Android solo admite una cámara en su SDK. Es probable que esto se agregue en una futura versión de Android.

CommonsWare
fuente
1
¿Esta declaración también es válida para Android 2.2?
ozmank
2
@ozmank: Sí, la compatibilidad con varias cámaras no se agregó hasta Android 2.3.
CommonsWare
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();
    }
}
Mahesh
fuente
3
Buen funcionamiento en Galaxy S Importante "ID de cámara" no "ID de cámara"
Mahesh
3
Nunca asuma que 90 grados le darán la rotación correcta para el retrato. Es diferente en muchos dispositivos.
colintheshots
4

Para API 21 (5.0) y posterior, puede utilizar la API de 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.
        }
    }
}
Airsource Ltd
fuente
4

Para abrir la cámara trasera : -

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

Para abrir la cámara frontal : -

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)

No pude hacer que funcione para API 28 y superior. Además, en algunos dispositivos no es posible abrir la cámara frontal directamente (depende del fabricante).

Shubham Raitka
fuente
2

Con el lanzamiento de Android 2.3 (Gingerbread), ahora puede usar la android.hardware.Cameraclase para obtener la cantidad de cámaras, información sobre una cámara específica y obtener una referencia a una cámara específica Camera. Consulte las nuevas CameraAPI aquí .

Wesley Wiser
fuente
1

build.gradle

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

Establecer vista

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);
Dheerendra Mitm
fuente
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();
}

/ * Esta no es la forma correcta, es una solución para dispositivos más antiguos que ejecutan Android 4.0 o más. Esto se puede utilizar con fines de prueba, pero no se recomienda para el desarrollo principal. Esta solución solo puede considerarse una solución temporal. Pero esta solución ha ayudado a muchos, así que no tengo la intención de eliminar esta respuesta * /

Amalan Dhananjayan
fuente
7
No creo que sea un uso documentado. open (int id) acepta la identificación, no la posición de la cámara
XY
13
elimine esta respuesta engañosa
Alex Cohn
13
@AmalanDhananjayan: vea, por ejemplo, el comentario de @Matthias arriba : ... Me tomó un tiempo darme cuenta de que la orientación de la cámara no es necesariamente la misma que el índice de la cámara. Por ejemplo, mi tableta tiene solo una cámara (índice: 0) pero orientada hacia el frente (índice orientado: 1). Por lo tanto, usar un código simple como Camera.open (CameraInfo.CAMERA_FACING_FRONT) no tiene sentido.
Alex Cohn
6
Esto es una tontería. Ni siquiera intentes usar esto.
Adam
4
Esto es espantoso. NUNCA hagas esto. Esta respuesta debería prohibirse. Camera.open () acepta una identificación de cámara, no el valor ordinal de la cámara que mira. Esto falla en una minoría significativa de dispositivos y solo funciona por pura suerte.
colintheshots