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

6
我正在开发一个应用程序,想要以特定的时间间隔闪烁闪光灯。以下是我遵循的步骤:
1)设置特定时间间隔的计时器。
2)在run()方法中编写打开和关闭闪光灯的代码。
但是不同设备上闪烁频率不同。计时器时间对于所有设备都是相同的,我还在其中加入了Log,得到的值也是相同的,但问题仍然存在。
这是硬件问题吗?因为不同设备的硬件不同。我还在上测试过(通过将相同的代码转换为iOS),但闪光灯闪烁比Android快得多。
对于Android,我已经在Nexus 4、Motorola G2、Sony Xperia Neo上进行了测试,一切正常。
问题出现在Nexus 5和Samsung 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);

你的计时器周期或PWM占空比是多少? - Bojan Kseneman
据我所知,这取决于硬件,计时器实现可运行接口,而可运行接口会导致消息被推入队列。 - Murtaza Khursheed Hussain
可能,当消息排队时,由内核执行。附言:我可能错了。 - Murtaza Khursheed Hussain
没有,我还没有发布。 - Mitesh Shah
@stupefy 不,我仍在寻找正确的答案。 - Syed Raza Mehdi
显示剩余11条评论
4个回答

1
我也曾经遇到手电筒的问题,原因与定时器无关,而是与你打开和关闭闪光灯的方式有关。在某些设备上,比如Nexus 5,你需要在布局中使用SurfaceView并使用它。请告诉我们你打开和关闭闪光灯的方法。

我已经在Nexus 5上使用了SurfaceView。但是,在不同的设备上,闪光灯的闪烁间隔仍然不同。 - Mitesh Shah
1
有一个很棒的新的 Android 库可以解决这个问题 https://github.com/Abhi347/NoobCameraFlash - David

1
这是一个老问题,但今天仍然存在,所以我将发布我是如何解决的。
问题在于调用打开或关闭LED需要不同的时间来穿过Android操作系统。处理这些调用的方式取决于手机。
首先,您需要测量从调用开始打开和关闭LED到完成所需的时间。使用相机输入,将手机靠近表面并测量帧中亮度的变化。如果使用OpenGL,可以使用glReadPixels仅读取每个帧的中心线。由于调用的长度取决于操作系统的状态,因此您需要进行多次测量。最好没有缓冲区或具有固定帧缓冲区,以便帧的时间是可靠的(这可能不适用于压缩)。我使用了OpenGL和SurfaceTexture,这是一种快速的方法。
现在,您知道调用穿越操作系统所需的最小(1)和最大(2)时间。使用这些信息,您可以尽可能快地使手机上的LED闪烁。为了真正发挥其最大效益,在最大(2)时间之前启动第二个调用闪光灯; maximum(2) - minium(1)。
使用上述技巧,闪烁速度主要取决于呼叫遍历的最小和最大时间差异。这通常在每个手机上都非常不同,从10毫秒到100毫秒以上。
还要注意,由于呼叫遍历时间的测量是通过相机进行的,因此时间会被舍入为33毫秒段(@30fps)。

1
    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);

请考虑编辑您的帖子,添加更多关于代码的解释以及为什么它可以解决问题的说明。仅含代码的答案(即使它可以正常工作)通常无法帮助提问者理解他们的问题。 - SuperBiasedMan

0

也许你可以尝试使用类似闹钟功能的函数:

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

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

你可以为闹钟设置重复周期。设置两个闹钟,一个用于开启,一个用于关闭。 即使手机工作繁忙,闹钟也会根据时钟时间工作。因此,可能会出现误关或误开的情况,但解决方案是相同的。

另外,你正在使用200毫秒。对于设备来说,捕捉如此小的时间间隔很困难。也许你可以尝试增加时间间隔?


谢谢您的回复。事实上,我的频率是从0到100。因此,我需要相应地给闹钟一定的时间,以便在所有设备上以相同的间隔显示手电筒。我正在尝试使用AlarmManager,并将让您知道我的输出结果。 - Mitesh Shah
那么,假如这样的话,我们可以创建一个队列,用于闪烁,并且一个可运行对象来将闪烁类型(开或关)添加到队列中。如果设备因其他程序而运行缓慢,队列将收集多个命令(开/关),并在设备恢复正常时执行。而可运行对象将是一个无限循环,其中包含Thread.sleep(ms)。你试过这种方法吗? - Saidolim
是的,我正在使用相同的 Thread.sleep(); 来设置特定的时间间隔。但是,闪烁时间因设备而异。 - Mitesh Shah
你尝试过使用LockSupport.parkNanos(nanos)吗?就像这个链接中的示例:http://stackoverflow.com/a/20729245/4953620 - Saidolim
没有,我还没有用过。让我试试看。 - Mitesh Shah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接