Android: Front Cameras are not Cameras

Let’s say you want to make an app that includes the occasional taking of a photo (i.e. for the profile pic) but you want to have it in-app and not launch the default intent.

Of course you follow the instructions for “Building a camera App” from the official website.

But there are a few points where the API is not obvious and can drive you mad. Specially if you are using a 2012 Nexus 7 as a test device (or any device that has front facing camera only).

Checking the hardware

Here is where the fun begins. Because this is not a killer feature, we won’t request the feature in the manifest, but check it in the code (as the documentation suggests)

getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)

Returns false. So it seems there is no camera. Let’s try something else.

Camera.getNumberOfCameras();

This returns 1. It seems there is a camera. Hmmm.

The documentation takes us out of our error. FEATURE_CAMERA means:

The device has a camera facing away from the screen.

There is FEATURE_CAMERA_ANY, but that is API level 17, and we are “only” minSDK=14, so we can not use it. We also have FEATURE_CAMERA_FRONT, we are saved.

The way to check if a device has any camera is:

PackageManager pm = getPackageManager();
boolean backCamera = pm.hasSystemFeature(PackageManager.FEATURE_CAMERA);
boolean frontCamera = pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT);
return backCamera || frontCamera;

Or just use Camera.getNumberOfCameras().

Be aware that if the camera feature is requested in you manifest, your app will not be available on devices with only a front facing camera. Maybe you want that, maybe not.

Opening the Camera

The fun continues when we try to open the camera. If we have more than 1 camera, we can select the one we want, but if there is only 1 camera we can go ahead and open it

if (Camera.getNumberOfCameras() == 1) {
    return Camera.open();
}
else {
   // Select one camera
   return selectAndOpenCamera();
}

Except that -in our special case- this code returns null. Because, you know, when it says camera it means back facing camera. At least the documentation of Camera.open() is clear.

Creates a new Camera object to access the first back-facing camera on the device. If the device does not have a back-facing camera, this returns null.

You should, instead, try to open the first camera, That works.

Camera.open(0)

In the case of selecting which camera to open (i.e. if you want a front facing camera by default) you have to iterate over the cameras, check the CameraInfo of each of them, and open the one you want using the id.

And remember: For Android, camera means back-facing camera. Front facing cameras are not real cameras.