在Android中使用相机手电筒

我正在试图使用照相机LED手电筒在一个小部件。 我已经find了关于这个主题的几个线程(即后面提到的..),现在我试图控制光使用:

Camera cam = Camera.open(); Parameters p = cam.getParameters(); p.setFlashMode(Parameters.FLASH_MODE_TORCH); cam.setParameters(p); cam.release(); 

在AndroidManifest.xml中尝试了不同的权限,目前我有:

 <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.FLASHLIGHT"/> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" /> <uses-feature android:name="android.hardware.camera.flash" /> 

我在Galaxy Tab上testing了这个,因为我手边没有任何其他Android设备:灯不亮。 所以我现在有几个问题:

  1. 有什么办法来testing模拟器中的指示灯行为吗?
  2. 我在这里做错了什么?
  3. 根据这个问题处理同样的问题,它在Galaxy Tab上的作用是不同的。 怎么样?
  4. 最后,如果它的工作方式不同,我开始怀疑它是否仅仅是Galaxy Tab或其他设备是否也使用不同的方法。 那么testing就很难了,对我来说似乎很奇怪。

感谢任何见解!

顺便说一句,我快速testing快速设置 ,这里提到几次。 手电筒也不适用于快速设置。

请注意Galaxy Tab stil使用android 2.2。 我发现在2.2和2.3之间有一些变化。

评论:我知道它必须以某种方式工作,因为我发现市场上的其他应用程序与Galaxy Tab完美配合。

评论2:如果我设置cam.setParameters(p); 并直接通过getFlashMode()向摄像机询问当前状态,正确返回FLASH_MODE_TORCH。 但是,如果我释放相机并重新打开它,它将返回FLASH_MODE_OFF。 就好像Camera对象知道请求,但并不真正传递给硬件!

康斯坦丁评论后,我删除了cam.release(); 部分。 他是对的,如果你释放相机,设置不会持续。 如果你再次使用cam.open(),你会得到一个closures灯光的新实例。 尽pipe如此,光线仍然不能在星系标签上工作。 所以,如果你试图通过一个小部件来控制它,我想这很难保持清晰。 一旦后台服务完成,相机对象将自动释放,因此指示灯会再次closures。 我的问题依然存在,特别是为什么相机不能开机。

每个设备都有点不同。 三星特别喜欢让应用程序开发人员变得复杂。

在银河标签你应该很好:

 Camera cam; void ledon() { cam = Camera.open(); Parameters params = cam.getParameters(); params.setFlashMode(Parameters.FLASH_MODE_ON); cam.setParameters(params); cam.startPreview(); cam.autoFocus(new AutoFocusCallback() { public void onAutoFocus(boolean success, Camera camera) { } }); } void ledoff() { cam.stopPreview(); cam.release(); } 

如果这样做不起作用,那么最初可能需要设置FLASH_MODE_OFF并在startPreview之后将其更改。

设置参数后,请勿释放相机。 我发现在开始预览之后,闪光灯被激活(在手电筒模式下)。 (适用于摩托罗拉,2.1)

尝试激活它们之前,检查支持的闪光灯模式也是一个好主意。

在android上使用相机设置是最黑暗的voodoo:许多设备的行为是不同的,似乎没有可靠的方法将所有的代码都定位在一起。 最安全的方法是在调用onResume()方法时始终正确设置相机。 我也会考虑在onConfigChange()中做同样的事情 ,因为至less摩托罗拉屏幕锁可以强制你的应用程序进入肖像模式,重新启动它。

Ps我想,当你closures相机,本地相机应用程序closures,然后重新创build一个新的状态。

我用下面的方法完成了,它可以在很多手机上使用:

  String manuName = android.os.Build.MANUFACTURER.toLowerCase(); Camera mCamera; 

以下代码显示了如何打开和closures灯光:

  private void processOnClick() { if (manuName.contains("motorola")) { DroidLED led; try { led = new DroidLED(); led.enable(true); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { if (mCamera == null) { try { mCamera = Camera.open(); } catch (Exception e) { e.printStackTrace(); } } if (mCamera != null) { final Parameters params = mCamera.getParameters(); List<String> flashModes = params.getSupportedFlashModes(); if (flashModes == null) { return; } else { if (count == 0) { params.setFlashMode(Parameters.FLASH_MODE_OFF); mCamera.setParameters(params); mCamera.startPreview(); } String flashMode = params.getFlashMode(); if (!Parameters.FLASH_MODE_TORCH.equals(flashMode)) { if (flashModes.contains(Parameters.FLASH_MODE_TORCH)) { params.setFlashMode(Parameters.FLASH_MODE_TORCH); mCamera.setParameters(params); } else { // Toast.makeText(this, // "Flash mode (torch) not supported",Toast.LENGTH_LONG).show(); params.setFlashMode(Parameters.FLASH_MODE_ON); mCamera.setParameters(params); try { mCamera.autoFocus(new AutoFocusCallback() { public void onAutoFocus(boolean success, Camera camera) { count = 1; } }); } catch (Exception e) { e.printStackTrace(); } } } } } } if (mCamera == null) { return; } } private void processOffClick() { if (manuName.contains("motorola")) { DroidLED led; try { led = new DroidLED(); led.enable(false); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { if (mCamera != null) { count = 0; mCamera.stopPreview(); } } } 

下面是DroidLED类:

  class DroidLED { private Object svc = null; private Method getFlashlightEnabled = null; private Method setFlashlightEnabled = null; @SuppressWarnings("unchecked") public DroidLED() throws Exception { try { // call ServiceManager.getService("hardware") to get an IBinder for the service. // this appears to be totally undocumented and not exposed in the SDK whatsoever. Class sm = Class.forName("android.os.ServiceManager"); Object hwBinder = sm.getMethod("getService", String.class).invoke(null, "hardware"); // get the hardware service stub. this seems to just get us one step closer to the proxy Class hwsstub = Class.forName("android.os.IHardwareService$Stub"); Method asInterface = hwsstub.getMethod("asInterface", android.os.IBinder.class); svc = asInterface.invoke(null, (IBinder) hwBinder); // grab the class (android.os.IHardwareService$Stub$Proxy) so we can reflect on its methods Class proxy = svc.getClass(); // save methods getFlashlightEnabled = proxy.getMethod("getFlashlightEnabled"); setFlashlightEnabled = proxy.getMethod("setFlashlightEnabled", boolean.class); } catch(Exception e) { throw new Exception("LED could not be initialized"); } } public boolean isEnabled() { try { return getFlashlightEnabled.invoke(svc).equals(true); } catch(Exception e) { return false; } } public void enable(boolean tf) { try { setFlashlightEnabled.invoke(svc, tf); } catch(Exception e) {} } 

}

您的AndroidManifest.xml中必须设置以下权限:

  <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.FLASHLIGHT"/> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" /> <uses-feature android:name="android.hardware.camera.flash" /> 

这对我的HTC Desire …(与2.2)(当然与相机和手电筒的权限):

  Camera mycam = Camera.open(); Parameters p = mycam.getParameters();// = mycam.getParameters(); p.setFlashMode(Parameters.FLASH_MODE_TORCH); mycam.setParameters(p); //time passes try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } p.setFlashMode(Parameters.FLASH_MODE_OFF); mycam.release(); 

您也可以尝试添加表面视图。 请看我对Galaxy Nexus的LED手电筒的回答, 通过什么API控制?

 private Camera camera; void openCam(){ camera = Camera.open(); if (camera != null) { Camera.Parameters params = camera.getParameters(); camera.setParameters(params); } Camera.Parameters p = camera.getParameters(); p.setFlashMode(Parameters.FLASH_MODE_TORCH); camera.setParameters(p); } 

Manifest中设置权限:

 <uses-permission android:name="android.permission.FLASHLIGHT" android:permissionGroup="android.permission-group.HARDWARE_CONTROLS" android:protectionLevel="normal" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.flash" />