// -*- mode: java; c-basic-offset: 2; -*- /* * Copyright (C) 2012 ZXing authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.zxing.client.android.camera.open; /* import android.annotation.TargetApi; */ import android.hardware.Camera; import android.util.Log; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * Implementation for Android API 9 (Gingerbread) and later. This opens up the possibility of accessing * front cameras, and rotated cameras. */ /* @TargetApi(9) */ public final class GingerbreadOpenCameraInterface implements OpenCameraInterface { private static final String TAG = "GingerbreadOpenCamera"; /** * Opens a rear-facing camera with {@link Camera#open(int)}, if one exists, or opens camera 0. */ @Override public Camera open() { // We have to use reflection because we are currently linked against Froyo (2.2). try { Class AndroidCamera; AndroidCamera = Class.forName("android.hardware.Camera"); int numCameras = ((Integer) invokeStaticMethod(getMethod(AndroidCamera, "getNumberOfCameras"))).intValue(); if (numCameras == 0) { Log.w(TAG, "No cameras!"); return null; } int index = 0; Class CameraInfo = Class.forName("android.hardware.Camera$CameraInfo"); Field facingField = CameraInfo.getField("facing"); while (index < numCameras) { Object cameraInfo = CameraInfo.getConstructor().newInstance(); AndroidCamera.getMethod("getCameraInfo", int.class, CameraInfo).invoke(null, index, cameraInfo); if (facingField.getInt(cameraInfo) == CameraInfo.getDeclaredField("CAMERA_FACING_BACK").getInt(CameraInfo)) break; index++; } if (index < numCameras) { Log.i(TAG, "Opening camera #" + index); } else { Log.i(TAG, "No camera facing back; returning camera #0"); index = 0; } Camera camera = (Camera) getMethod(AndroidCamera, "open", int.class).invoke(null, index); return camera; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } // Reflection helper methods private static Method getMethod(Class clazz, String name) { try { return clazz.getMethod(name, new Class[0]); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } private static Method getMethod(Class clazz, String name, Class<?>... parameterTypes) { try { return clazz.getMethod(name, parameterTypes); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } private static Object invokeStaticMethod(Method method) { try { return method.invoke(null); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); cause.printStackTrace(); if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } else { throw new RuntimeException(cause); } } } private static Object invokeMethod(Method method, Object thisObject, Object... args) { try { return method.invoke(thisObject, args); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); cause.printStackTrace(); if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } else { throw new RuntimeException(cause); } } } private static Object invokeMethodThrowsIllegalArgumentException(Method method, Object thisObject, Object... args) throws IllegalArgumentException { try { return method.invoke(thisObject, args); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); cause.printStackTrace(); if (cause instanceof IllegalArgumentException) { throw (IllegalArgumentException) cause; } else if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } else { throw new RuntimeException(e); } } } private static Object invokeMethodThrowsIOException(Method method, Object thisObject, Object... args) throws IOException { try { return method.invoke(thisObject, args); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); cause.printStackTrace(); if (cause instanceof IOException) { throw (IOException) cause; } else if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } else { throw new RuntimeException(e); } } } }