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.