android - 尝试打开 Led 闪光灯电源时延迟几秒钟

标签 android camera android-camera led

我试图打开 LED 闪光灯,但 LED 闪光灯在延迟几秒钟后才打开。

我的手机有一个内置手电筒,当我点击它时,闪光灯会立即打开。

这里有什么问题?

这是我的代码:

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();
                    }
                }

                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) {
                    mCamera.stopPreview();
                    mCamera.release();
                }
            }
        }

DroidLED 类:

import java.lang.reflect.Method;

import android.os.IBinder;

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) {}
    }
}

我从关于 stackoverflow 的一些答案中获取了这段代码。

感谢您的协助!

最佳答案

摩托罗拉的延迟是否很高?

这只是一个猜测,但 DroidLED 构造函数调用了昂贵的系统初始化。 你不能这样做吗?

public class MyWidgetClickHandler {
    private DroidLED = null;
    public MyWidgetClickHandler(string ManuName) {
        // This is slow. It will run once at initialization.
        if (ManuName != null && ManuName.toLowerCase().contains("motorola"))
            DroidLED = new DroidLED();
    }

    public void processOnClick() {
        if (DroidLED != null)
            DroidLED.enable(true);
        else
            ; // ... TODO
    }

    public void processOffClick() {
        if (DroidLED != null)
            DroidLED.enable(false);
        else
            ; // ... TODO
    }
}

可能还有更多。例如,您可以使用 enableisEnabled 创建一个 LED interface,并为其提供两个实现。一个是 DroidLED,另一个是 CommonCameraLED。 有了这个,它看起来像这样:

public class LEDFactory {
    public static LED createLED(string ManuName) {
        if (ManuName != null && ManuName.toLowerCase().contains("motorola"))
            return new DroidLED();
        else
            return new CommonCameraLED();
    }
}

public class MyWidgetClickHandler {
    private LED myLed = null;
    public MyWidgetClickHandler(string ManuName) {
        myLed = LEDFactory.createLED(ManuName);
    }

    public void processOnClick() {
        myLed.enable(true);
        // NOTHING TO DO
    }

    public void processOffClick() {
        myLed.enable(false);
        // NOTHING TO DO
    }
}

你也可以创建一个线程来初始化,这样手机就不会启动慢了。

关于android - 尝试打开 Led 闪光灯电源时延迟几秒钟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18579861/

相关文章:

android - 从 Android 中的 shell 命令安装/卸载

ios - 如何在 PageViewController 中预加载相机以便没有加载动画?

android-camera - 使用相机拍摄照片时数据为空 (Nexus 7)

android Camera2 Jpeg回调的命中超时

android - 如何将语音识别与我的相机应用程序集成?

android - 拍照总是在onActivityResult(..)中返回RESULT_CANCELED(0)

Android 设计指南 - 列表操作按钮

android - 即使不在同一网络中,我们也可以从 Android 设备连接到 iPhone 吗?

android - Android 上的祝贺屏幕

c# - 错误 : Object is currently in use elsewhere.