Android - 相机闪光灯在不同设备中以错误的间隔闪烁

时间:2015-05-22 10:55:58

标签: android flash led

我正在开发一款应用,我希望在特定的时间间隔内闪烁闪光灯。

以下是我遵循的步骤。

1)将Timer设置为特定的间隔。

2)在run()方法中,我完成了TurnOn和TurnOff闪存的代码。

但闪光灯闪烁的间隔在不同设备上有所不同。所有设备的定时器时间都相同,我也在其间设置了一个Log,我得到相同的值,但问题仍然存在。

是硬件问题,因为不同设备的硬件不同。我也在iPhone 5s进行了测试(通过在iOS中转换相同的代码),但闪烁闪烁比Android快得多。

对于Android,我已经在Nexus 4,Motorola G2,Sony Xperia Neo上进行了测试,它运行良好。

问题在于Nexus 5和三星Galaxy S4。

修改

计时器代码:

long delayLong = 200;
long timerValueLong = 500;
Timer timer;

timer = new Timer();
timer.schedule(new TimerTask() {
    @Override
    public void run() {
        if (!mLightOn) {
            turnOnFlash();
        } else {
            turnOffFlash();
        }
    }
}, delayLong, timerValueLong);

4 个答案:

答案 0 :(得分:1)

手电筒有同样的问题,问题与手机无关。这是关于如何打开和关闭闪光灯。在某些设备(如Nexus 5)上,您必须在布局中使用并使用SurfaceView。向我们展示用于打开和关闭手电筒的方法会很有用。

答案 1 :(得分:1)

这是一个较老的问题,但问题仍然存在,所以我会发布我是如何解决这个问题的。

问题在于打开或关闭LED的调用需要花费不同的时间来遍历Android操作系统。处理这些电话的方式取决于电话。

首先,您需要测量从打电话开始,LED开启和关闭所需的时间。使用相机输入,使手机靠近表面并测量相框的亮度变化。如果使用OpenGL,您可以使用glReadPixels,并且每帧只读出中心线。您需要进行多次测量,因为呼叫可以更短或更长,具体取决于操作系统的状态。优选地,您希望没有缓冲区或帧的固定缓冲区,因此帧的定时是可靠的(压缩可能不是这种情况)。我使用OpenGL和SurfaceTexture,这是一种活泼的方式。

您现在知道调用遍历操作系统所需的最短(1)和最长(2)时间。使用此信息可以使LED在手机上尽快闪烁。要真正充分利用它,在最长(2)时间过去之前开始第二次闪光调用;最大值(2) - minium(1)。

使用最后一个技巧,闪烁的速度主要取决于呼叫遍历的最小和最大时间的差异。这通常与每部手机非常不同,从10ms到100ms +。

另请注意,由于相机会测量呼叫遍历时间,因此将时间向上/向下舍入到33ms段(@ 30fps)。

答案 2 :(得分:0)

也许您可以尝试使用警报功能,如:

  1. https://developer.android.com/training/scheduling/alarms.html

  2. https://developer.android.com/reference/android/provider/AlarmClock.html

  3. 您可以设置警报的重复周期。制作2个闹钟,一个用于开,一个用于关闭。 即使手机工作很辛苦,闹钟也会根据时钟时间而工作。所以也许它不会关闭和两次错误,但解决方案将是相同的。

    你也使用200毫秒。设备很难抓住这么短的时间间隔。也许你会试着增加你的时间间隔?

答案 3 :(得分:0)

    long delayLong = 20;
    long timerValueLong = 100;
    Timer timer;
    final Parameters p = camera.getParameters();
    timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            if (!isLighOn) {
                p.setFlashMode(Parameters.FLASH_MODE_ON);
                p.setFlashMode(Parameters.FLASH_MODE_TORCH);
                camera.setParameters(p);
                isLighOn = true;
            } else {
                p.setFlashMode(Parameters.FLASH_MODE_OFF);
                camera.setParameters(p);
                isLighOn = false;
            }
        }
    }, delayLong, timerValueLong);