Derek Gebhard, Solutions Architect, a2z Development Center Inc., an Amazon.com company, is our guest blogger for this post.
If you are optimizing your app for Kindle Fire HD support, one of the things to think through is camera integration. In this blog post, we walk through the front-facing camera optimization Allrecipes explored as they added Kindle Fire HD support to their popular Allrecipes.com Dinner Spinner for Android app.
When developing for the Kindle Fire HD, you should keep in mind that the Kindle Fire HD has a front-facing camera. Most Android devices come with a rear camera, and a number of apps—such as Dinner Spinner—take advantage of this. This means you will need to adjust a few things in your app if you want to use the Kindle Fire HD’s camera. The interesting challenge that Allrecipes.com ran into when exploring this support is that the front-facing camera API became available in Android 2.3 (Gingerbread), API level 9, which can be a problem if you want to support older Android API levels and other devices with the same code. The Allrecipes app development team solved this by checking if the rear camera is available, and if not, using reflection to see if they can fall back to the front-facing camera.
Here’s a look at the code for how you could implement this in your app to obtain the Camera object:
public static Camera getCameraInstance() {
Camera camera = null;
try {
try {
// Attempt to getthe first, back-facing camera
camera = Camera.open();
} catch (Exception e) {
Log.e(TAG, "Camerafailed to open: " + e.getLocalizedMessage());
}
if (camera == null) { // Failed to open camera
// Obtain classesand methods needed for accessing front-facing camera
// Use reflectionto support API levels lower than 9
Class<?> cameraClass = Camera.class;
Class<?> cameraInfoClass =Class.forName("android.hardware.Camera$CameraInfo");
Object cameraInfo = null;
Method getNumCamerasMethod =cameraClass.getMethod("getNumberOfCameras");
Method getCameraInfoMethod = null;
Field facingField = null;
int cameraCount = 0;
// Verify theneeded class and method exist
if (getNumCamerasMethod != null && cameraInfoClass != null) {
cameraCount = (Integer)getNumCamerasMethod.invoke(null, (Object[]) null);
// Obtain objectsneeded for checking if a camera is front-facing
cameraInfo =cameraInfoClass.newInstance();
getCameraInfoMethod =cameraClass.getMethod("getCameraInfo", Integer.TYPE, cameraInfoClass);
if (cameraInfo != null) {
facingField =cameraInfo.getClass().getField("facing");
}
}
// Iteratethrough cameras to obtain front-facing camera
if (getCameraInfoMethod != null && facingField != null) {
for (int cameraIndex = 0; cameraIndex <cameraCount; cameraIndex++) {
getCameraInfoMethod.invoke(null, cameraIndex, cameraInfo);
int facing =facingField.getInt(cameraInfo);
if (facing == 1) { // 1 == Camera.CameraInfo.CAMERA_FACING_FRONT
// Open front-facing camera
Method cameraOpenMethod =cameraClass.getMethod("open", Integer.TYPE);
if (cameraOpenMethod != null) {
try {
camera = (Camera)cameraOpenMethod.invoke(null, cameraIndex);
} catch (Exception e){
Log.e(TAG, "Camerafailed to open: " + e.getLocalizedMessage());
}
}
}
}
}
}
} catch (Exception e){
Log.e(TAG, "Camerafailed to open: " + e.getLocalizedMessage());
}
return camera; // returns null if camera isunavailable
}
The above function is not only useful if you are addingsupport for the Kindle Fire HD to your app and want to allow existing rear-facingcamera scenarios to continue working, it is also useful when you are startingoff creating a Kindle Fire HD app and want to leverage the rear camera whenyou add support for other Android devices. The one thing to keep in mind isthat reflection is more expensive than calling the APIs directly. You shouldonly use this method if you need to support an API level lower than 9.
For moreinformation on leveraging the Camera object to take pictures and videos you cancheck out the following documentation: