From: srowen Date: Sat, 27 Feb 2010 09:35:25 +0000 (+0000) Subject: Try out hacky support for enabling the front light on some devices X-Git-Url: http://git.rot13.org/?a=commitdiff_plain;h=0fc2001180853a92a28c501ec29b53d0c0c86c43;hp=5873980f24b728e82504373a5bf289252756d6d2;p=zxing.git Try out hacky support for enabling the front light on some devices git-svn-id: http://zxing.googlecode.com/svn/trunk@1223 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- diff --git a/android/src/com/google/zxing/client/android/CameraManager.java b/android/src/com/google/zxing/client/android/CameraManager.java index 72d81efe..9b64ef1c 100755 --- a/android/src/com/google/zxing/client/android/CameraManager.java +++ b/android/src/com/google/zxing/client/android/CameraManager.java @@ -154,6 +154,7 @@ final class CameraManager { } setCameraParameters(); + FlashlightManager.enableFlashlight(); } } @@ -162,6 +163,7 @@ final class CameraManager { */ public void closeDriver() { if (camera != null) { + FlashlightManager.disableFlashlight(); camera.release(); camera = null; } diff --git a/android/src/com/google/zxing/client/android/FlashlightManager.java b/android/src/com/google/zxing/client/android/FlashlightManager.java new file mode 100644 index 00000000..e8617889 --- /dev/null +++ b/android/src/com/google/zxing/client/android/FlashlightManager.java @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2010 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; + +import android.os.IBinder; +import android.util.Log; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * This class is used to activate the weak light on some camera phones (not flash) + * in order to illuminate surfaces for scanning. There is no official way to do this, + * but, classes which allow access to this function still exist on some devices. + * This therefore proceeds through a great deal of reflection. + * + * See + * http://almondmendoza.com/2009/01/05/changing-the-screen-brightness-programatically/ and + * + * http://code.google.com/p/droidled/source/browse/trunk/src/com/droidled/demo/DroidLED.java. + */ +final class FlashlightManager { + + private static final String TAG = FlashlightManager.class.getName(); + + private static Object iHardwareService; + private static Method setFlashEnabledMethod; + static { + iHardwareService = getHardwareService(); + setFlashEnabledMethod = getSetFlashEnabledMethod(iHardwareService); + if (iHardwareService == null) { + Log.i(TAG, "This device does supports control of a flashlight"); + } else { + Log.i(TAG, "This device does not support control of a flashlight"); + } + } + + private FlashlightManager() { + } + + private static Object getHardwareService() { + Class serviceManagerClass = maybeForName("android.os.ServiceManager"); + if (serviceManagerClass == null) { + return null; + } + + Method getServiceMethod = maybeGetMethod(serviceManagerClass, "getService", String.class); + if (getServiceMethod == null) { + return null; + } + + Object hardwareService = invoke(getServiceMethod, null, "hardware"); + if (hardwareService == null) { + return null; + } + + Class iHardwareServiceStubClass = maybeForName("android.os.IHardwareService$Stub"); + if (iHardwareServiceStubClass == null) { + return null; + } + + Method asInterfaceMethod = maybeGetMethod(iHardwareServiceStubClass, "asInterface", IBinder.class); + if (asInterfaceMethod == null) { + return null; + } + + return invoke(asInterfaceMethod, null, hardwareService); + } + + private static Method getSetFlashEnabledMethod(Object iHardwareService) { + if (iHardwareService == null) { + return null; + } + Class proxyClass = iHardwareService.getClass(); + return maybeGetMethod(proxyClass, "setFlashlightEnabled", boolean.class); + } + + private static Class maybeForName(String name) { + try { + return Class.forName(name); + } catch (ClassNotFoundException cnfe) { + // OK + return null; + } catch (RuntimeException re) { + Log.w(TAG, "Unexpected error while finding class " + name, re); + return null; + } + } + + private static Method maybeGetMethod(Class clazz, String name, Class... argClasses) { + try { + return clazz.getMethod(name, argClasses); + } catch (NoSuchMethodException nsme) { + // OK + return null; + } catch (RuntimeException re) { + Log.w(TAG, "Unexpected error while finding method " + name, re); + return null; + } + } + + private static Object invoke(Method method, Object instance, Object... args) { + try { + return method.invoke(instance, args); + } catch (IllegalAccessException e) { + Log.w(TAG, "Unexpected error while invoking " + method, e); + return null; + } catch (InvocationTargetException e) { + Log.w(TAG, "Unexpected error while invoking " + method, e.getCause()); + return null; + } catch (RuntimeException re) { + Log.w(TAG, "Unexpected error while invoking " + method, re); + return null; + } + } + + static void enableFlashlight() { + setFlashlight(true); + } + + static void disableFlashlight() { + setFlashlight(false); + } + + private static void setFlashlight(boolean active) { + if (iHardwareService != null) { + invoke(setFlashEnabledMethod, iHardwareService, active); + } + } + +}