尝试打开 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();
                }
            }
        }

机器人发光二极管类:

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

我从堆栈溢出的一些答案中获取了这段代码。

感谢您的帮助!

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

这只是一个猜测,但 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
    }
}

可能还有更多。例如,您可以创建一个包含 enableisEnabledLED 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
    }
}

您还可以创建一个用于初始化的线程,以便手机不会启动缓慢。

我刚刚遇到了同样的问题并找到了解决方案,但我使用三星Galaxy S2进行了测试。此代码应该适用于每个设备。

分析每个功能时,我发现设置相机所需的一些调用,总和延迟长达500毫秒,使频闪效果变得不可能。

我的解决方案是将所有这些函数移动到我想获取相机时调用的单独函数中,并将"打开"代码减少到对Camera.setParameters()的调用。通过这样做,延迟降至仅4ms

例如(简化代码只是为了证明这一点(:

// First get the camera for your app (Keep this variables as class 
members so the live between functions)
private void acquireCamera()
{
    try
    {
        // Get camera
        cam = Camera.open(); 
        // This is not on your code but you should do it for compatibility
        mSurfaceTexture = new SurfaceTexture(0);
        cam.setPreviewTexture(mSurfaceTexture);
        cam.startPreview();
        camParams = cam.getParameters();
    }
    catch(IOException e)
    { /*...*/ }
}
// Then turn on / off as many times you want.
private void setTorch(boolean on)
{
    camParams.setFlashMode(on? Camera.Parameters.FLASH_MODE_TORCH : Camera.Parameters.FLASH_MODE_OFF);
    cam.setParameters(camParams);
}
// Finally release the camera when you`re done
private void releaseCamera
{
    camParams = null;
    cam.stopPreview();
    mSurfaceTexture = null;
    cam.release();
}

最新更新