利用反射解决有些手机无法使用手电筒的问题
2011-11-16 17:13
351 查看
本次项目,遇到索尼手机无法使用手电筒的问题,但是HTC等用官方的方法可以搞定,经过调查发现,谷歌这小子把API隐藏了,于是乎想起了搞web时使用的反射,但是android的不能直接反射出private的常量和方法,因为andorid貌似把Class.java这个东西重新搞了,其实JDK里面是有这个方法的,需要
Class clazz=Class.forName("android.os.IHardwareService");
clazz.getClass().getDeclaredFields();
这样才能拿到,下面是手电筒的解决方法:
首先是一个管理类:
然后是具体调用方法:
今天生日,搞定了这么大个难题,实在爽.
Class clazz=Class.forName("android.os.IHardwareService");
clazz.getClass().getDeclaredFields();
这样才能拿到,下面是手电筒的解决方法:
首先是一个管理类:
public final class FlashlightManager { private static final String TAG = FlashlightManager.class.getSimpleName(); private static final Object iHardwareService; private static final Method setFlashEnabledMethod; private static final Method getFlashEnabledMethod; /** * Use Static Intialize Object,Setting HardwareService Manager Object and * flash method. */ static { iHardwareService = getHardwareService(); setFlashEnabledMethod = getMethod("setFlashlightEnabled", iHardwareService, boolean.class); getFlashEnabledMethod = getMethod("getFlashlightEnabled", iHardwareService, null); //here must set null if (iHardwareService == null) { Log.v(TAG, "This device does supports control of a flashlight"); } else { Log.v(TAG, "This device does not support control of a flashlight"); } } /** * Get Hardware Service * * @return */ private static Object getHardwareService() { // Use reflect get system service mamger object Class<?> serviceManagerClass = maybeForName("android.os.ServiceManager"); if (serviceManagerClass == null) { return null; } // Get getService function method object 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); } /** * Use reflect * * @param methodName * @param iHardwareService * @param argClasses * @return */ private static Method getMethod(String methodName, Object iHardwareService, Class<?>... argClasses) { if (iHardwareService == null) { return null; } Class<?> proxyClass = iHardwareService.getClass(); // test Method[] methods = proxyClass.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { Log.i("method---", methods[i].getName()); } return maybeGetMethod(proxyClass, methodName, argClasses); } 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; } } public static void enableFlashlight(Camera camera) { setFlashlight(camera, true); } public static void disableFlashlight(Camera camera) { setFlashlight(camera, false); } /** * Set Flahlight if activate * * @param camera * @param active */ private static void setFlashlight(Camera camera, boolean active) { if (iHardwareService != null && setFlashEnabledMethod != null && getFlashEnabledMethod != null) { try { setFlashEnabledMethod.invoke(iHardwareService, active); Boolean enabled = (Boolean) getFlashEnabledMethod.invoke(iHardwareService, (Object[]) null); if (active && !enabled) setFlashlightConventional(camera, active); } catch (Exception e) { setFlashlightConventional(camera, active); } } else { setFlashlightConventional(camera, active); } } private static void setFlashlightConventional(Camera camera, boolean active) { Parameters p = camera.getParameters(); // Set if (active) p.setFlashMode(Parameters.FLASH_MODE_TORCH); else p.setFlashMode(Parameters.FLASH_MODE_OFF); camera.setParameters(p); } }
然后是具体调用方法:
private boolean isOpen; private void flashLightoOpenOrClose(){ //Get System Camera if(camera==null)camera=Camera.open(); isOpen=!isOpen; if(isOpen){ FlashlightManager.enableFlashlight(camera); }else{ FlashlightManager.disableFlashlight(camera); } }
今天生日,搞定了这么大个难题,实在爽.
相关文章推荐
- 升级到安卓5.0后,和包提示:“检测到您的手机或sim卡不完全支持和包业务,部分NFC相关功能将无法正常使用”的问题解决办法
- thinkphp使用view的时候无法利用phpexcel导出数据问题的解决
- Android手机JmDNS的使用以及解决某些品牌手机Multicast无法接收组播消息的问题
- 使用UIAutomator在Android6.0执行,无法向手机SD卡写入内容问题的解决
- [C#] 解决Silverlight反射安全关键(SecuritySafeCritical)时报“System.MethodAccessException: 安全透明方法 XXX 无法使用反射访问”的问题
- 解决Mac下MX4手机无法连接adb问题之解决方案
- 如何解决烦人的VS.NET2003编译时“无法将程序集复制到文件,另一个程序正在使用,进程无法访问”的问题?
- 升级win10后有线网卡无法使用问题的解决方法
- html5新特性:利用history的pushState等方法来解决使用ajax导致页面后退和前进的问题
- Linux/Windows等系统无线网卡无法使用时利用手机共享网络救急
- 在使用Gson的toJson()方法转为json字符串的时候无法显示中文和符号的问题(已解决)
- 解决myeclipse中新建javaweb工程,无法使用Web App Libraries问题
- rtl8723bs linux网卡驱动识别问题,无法使用无线的解决方法
- 使用startx无法进入图形界面的问题终于解决
- Android手机无法使用debug解决方法
- 使用NTP服务器完美解决VMware Linux时间无法同步问题
- smarty如何解决css无法使用的问题
- 解决IPMITool无法在SELS上使用的问题
- Myeclipse中文件已经上传到服务器目录下,文件也没有被占用,但是页面中无法读取和使用问题的解决方法