85

More generally, if a device has more than one embedded camera, is there a way to initialize one of them in particular?

I didn't find it in Android reference documentation:

Samsung SHW-M100S has two cameras. If there is no reference to use two cameras, any idea how Samsung did...?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sol
  • 907
  • 1
  • 7
  • 5
  • possible duplicate of [How to use Front Facing Camera on Samsung Galaxy S](http://stackoverflow.com/questions/4241292/how-to-use-front-facing-camera-on-samsung-galaxy-s) – Esteban Küber Dec 28 '10 at 00:07

10 Answers10

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

Add the following permissions in the AndroidManifest.xml file:

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

Note: This feature is available in Gingerbread(2.3) and Up Android Version.

Crisoforo Gaspar
  • 3,740
  • 2
  • 21
  • 27
  • Is it possible to use this somehow with the `Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);` technique to open the existing camera app? – loeschg May 21 '13 at 20:00
  • 3
    @loeschg `Intent` handles camera action in its own way. This technique is used when you are using `SurfaceView` to exploit camera functionality. –  May 22 '13 at 03:36
  • that's what I figured. Thanks! – loeschg May 22 '13 at 15:03
  • 2
    Very cool post. Took me a while to figure out that camera facing is not neccessarily the same than the camera index. For example my tablet has only one camera (index: 0) but facing front (facing index: 1). Therefore using the simple code like Camera.open(CameraInfo.CAMERA_FACING_FRONT) is nonesense. – Matthias Feb 26 '14 at 09:52
  • @Matthias Agree with you mate. As we have different OEMs, our programming technique gets changed as per our needs. Thanks for highlighting. –  Feb 26 '14 at 13:23
  • not working with pie or oreo updated version of android – civani mahida Jan 20 '20 at 06:59
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"
Community
  • 1
  • 1
iantonuk
  • 1,178
  • 8
  • 28
10

As of Android 2.1, Android only supports a single camera in its SDK. It is likely that this will be added in a future Android release.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
6

To open the back camera:-

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

To open the front 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)

I could not make it work for API 28 and above. Also, opening the front camera directly is not possible in some devices(depends on the manufacturer).

Shubham Raitka
  • 1,034
  • 8
  • 15
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();
    }
}
Crisoforo Gaspar
  • 3,740
  • 2
  • 21
  • 27
Mahesh
  • 57
  • 1
4

For API 21 (5.0) and later you can use the CameraManager API's

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
  • 32,379
  • 13
  • 71
  • 75
2

With the release of Android 2.3 (Gingerbread), you can now use the android.hardware.Camera class to get the number of cameras, information about a specific camera, and get a reference to a specific Camera. Check out the new Camera APIs here.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Wesley Wiser
  • 9,491
  • 4
  • 50
  • 69
1

build.gradle

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

Set View

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
  • 182
  • 1
  • 9
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();
}

/* This is not the proper way, this is a solution for older devices that run Android 4.0 or older. This can be used for testing purposes, but not recommended for main development. This solution can be considered as a temporary solution only. But this solution has helped many so I don't intend to delete this answer*/

Clive
  • 36,918
  • 8
  • 87
  • 113
Amalan Dhananjayan
  • 2,277
  • 1
  • 34
  • 47
  • 7
    I don't think it's documented usage. open(int id) accepts the id, not camera position – X.Y. Jan 20 '14 at 02:38
  • 13
    please remove this misleading answer – Alex Cohn Mar 05 '14 at 07:40
  • @AlexCohn Can you please explain why this answer should be removed. It seems like many of them are fine with the answer. – Amalan Dhananjayan Mar 05 '14 at 07:50
  • 13
    @AmalanDhananjayan: see for example the comment by [@Matthias](http://stackoverflow.com/users/1739297/matthias) [above](http://stackoverflow.com/a/4767832/192373): _…Took me a while to figure out that camera facing is not neccessarily the same than the camera index. For example my tablet has only one camera (index: 0) but facing front (facing index: 1). Therefore using the simple code like Camera.open(CameraInfo.CAMERA_FACING_FRONT) is nonesense._ – Alex Cohn Mar 05 '14 at 07:54
  • 6
    **This is balderdash. Don't even attempt to use this.** – Adam Feb 21 '15 at 01:14
  • 4
    This is horrific. Do not EVER do this. This answer should be banned. Camera.open() accepts a camera id, not the ordinal value of the camera facing! This fails across a significant minority of devices and only works through sheer dumb luck. – colintheshots Mar 23 '16 at 16:03
  • @AlexCohn Please stop defacing this answer and adding your flair to it. The objections in the comments are sufficient, posts shouldn't be edited to add meta information – Clive May 14 '17 at 09:16
  • @Clive: this approach was supported by Community: https://meta.stackoverflow.com/a/311430/192373 – Alex Cohn May 14 '17 at 09:22
  • 1
    I don't believe that's policy, just a somewhat popular opinion on that day. Flagged for mod to make the decision, easier that way @AlexCohn. If you want to rollback my rollback in lieu of that please do – Clive May 14 '17 at 09:34
  • @Clive, my experience getting mod attention has never been very successful. I will be glad if it works now. – Alex Cohn May 14 '17 at 09:36
  • @Clive, thanks, we did get mod attention. Was it helpful? – Alex Cohn Jun 08 '17 at 08:29
0

I found this works nicely.

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
}
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213