53

我正在尝试在小部件中使用相机 LED 手电筒。我找到了几个关于这个主题的线程(即后面提到的那个..),现在我正在尝试使用以下方法控制灯光:

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 上对此进行测试,因为我手头没有任何其他 Android 设备:灯没有打开。所以我现在有几个问题:

  1. 有什么方法可以测试模拟器中的 LED 灯行为吗?
  2. 我在这里做错了吗?
  3. 根据处理相同问题的这个问题,它在 Galaxy Tab 上的工作方式不同。如何?
  4. 最后,如果它的工作方式不同,我开始怀疑它是否只是 Galaxy Tab 还是其他设备也使用不同的方法。那时很难测试,对我来说似乎很奇怪。

感谢您的任何见解!

顺便说一句,我快速测试了这里多次提到的快速设置。手电筒也不适用于快速设置。

请注意,Galaxy Tab 仍然使用 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(),您将获得一个关闭灯的新实例。不过,灯仍然无法在银河选项卡上工作。所以,我想如果你当时试图通过一个小部件来控制它,就很难保持点亮。后台服务完成后,相机对象会自动释放,因此灯会再次关闭。我的问题仍然存在,尤其是为什么相机一开始就没有打开。

4

7 回答 7

34

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

在 Galaxy Tab 上,您应该擅长:

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 之后更改它。

于 2011-04-07T17:33:25.470 回答
18

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

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

在 android 上乱搞相机设置是最黑暗的巫术:许多设备的行为不同,似乎没有可靠的方法可以用一段代码将它们全部定位。最安全的选择是在调用onResume()方法时始终正确设置相机。我也会考虑在 onConfigChange()中做同样的事情,因为至少摩托罗拉屏幕储物柜可以强制您的应用程序进入纵向模式,完全重新启动它。

Ps 我想当你关闭相机时,本机相机应用程序会关闭,然后以全新状态重新创建。

于 2011-04-04T12:31:03.903 回答
11

我已经通过以下方式完成了它,它适用于许多手机:

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

下面的代码显示了如何关闭和打开灯:

  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" />
于 2012-09-21T18:03:28.813 回答
8

这适用于我的 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();
于 2011-04-05T14:05:48.330 回答
4

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

于 2012-03-02T09:30:07.420 回答
3

请使用此链接:

http://www.androidhive.info/2013/04/android-developing-flashlight-application/

这对我很有帮助。

于 2014-09-04T09:37:19.577 回答
1
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" />
于 2012-03-29T04:17:19.713 回答