屏幕关闭时,Android加速度计无法正常工作

mar*_*tin 68 android screen sensor accelerometer

我正在为计算机科学的最终论文开发一个应用程序,我需要收集并记录加速度计数据.我需要一整天才能获得它,因此存在严重的电池限制(例如,我无法启动屏幕).此外,这不是一个以市场为目标的应用程序,因此如果需要,做一些严重的黑客攻击,甚至低级C/C++编码是完全可以接受的.

众所周知,在许多设备上,加速计事件的监听器在屏幕关闭时停止生成事件(关于此问题的一些链接:http://code.google.com/p/android/issues/detail?id = 3708,加速度计当Droid/Nexus One屏幕关闭时,即使使用WakeLock,也会停止传送样本.我已经彻底搜索了一些替代方案,其中一些包括对我的设备不起作用的解决方法(LG P990,股票ROM).

所以会发生这样的事情:当你在服务中为android加速计传感器注册事件监听器时,它可以正常运行,直到屏幕关闭.我已经尝试在IntentService上的服务上注册eventListener,试图获取WakeLocks.关于唤醒锁,我可以验证服务是否仍在运行,观察LOGcat输出,但似乎加速度计进入睡眠模式.某些链接中提供的解决方法之一是使用IntentService的线程定期取消注册和重新注册事件侦听器,如下面的代码片段所示

synchronized private static PowerManager.WakeLock getLock(Context context) {
    if (lockStatic==null) {
        PowerManager mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE);

        lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,NAME);
        lockStatic.setReferenceCounted(true);
    }

    return(lockStatic);
}

@Override
protected void onHandleIntent(Intent intent) {

     sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
     sensorManager.unregisterListener(this);
     sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);


    synchronized (this) {
        boolean run = true;
        while (run){
            try {
                wait(1000);
                getLock(AccelerometerService.this).acquire();
                sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
                sensorManager.unregisterListener(this);
                sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
                Log.d("Accelerometer service", "tick!");

            } catch (Exception e) {
                run = false;
                Log.d("Accelerometer service", "interrupted; cause: " + e.getMessage());


            }
        }
    }       
}


@Override
public void onSensorChanged(SensorEvent event) {
    Log.d("accelerometer event received", "xyz: "+ event.values[0] + "," + event.values[1] + "," +  event.values[2]);
}
Run Code Online (Sandbox Code Playgroud)

这确实使每次我们取消注册/注册监听器时都会调用onSensorChange.问题是收到的事件总是包含相同的值,无论我摇动设备.

所以,基本上我的问题是:(忍受我,我差不多完成:P)

  1. 是否可以对加速计硬件进行低级访问(C/C++方法)而无需注册到事件监听器?

  2. 有没有其他解决方法或黑客?

  3. 任何拥有更新电话的人都可以测试固件3.0及更高版本中是否存在问题?

[UPDATE]

不幸的是,它似乎是一些手机的错误.我的答案中有更多细节.

mar*_*tin 67

基本上,这是我的手机的问题.其他用户报告说,这也适用于他们的手机,来自不同品牌但相同的Android版本.其他人完全没有问题 - 强烈表明这不是android的股票版本的问题,而是来自每个公司的硬件驱动程序的实现.

我需要提供恒定的加速度计数据,并且不能让加密狗为我测量这些数据 - 我有一个带蓝牙和加速度计的Arduino,所以我可以实现这个解决方案.因此,我认为手机的临时解决方案是让屏幕开启(变暗)并忽略电池消耗.稍后,我将使用另一个Android手机执行电池使用测试,该手机可以关闭屏幕.

有关该bug的更多信息

我已经研究了一些,并发现了其他Android用户的报告,我想也许我明白发生了什么.图书馆libsensors.so有手机传感器的驱动程序不是由谷歌开发的,而是由每个手机供应商开发的 - 当然,因为每个手机都有自己的特定硬件.Google只提供C头文件,以便开发人员知道他们必须实现的内容.在这些驱动程序的一些实现中,开发人员只需在屏幕关闭时关闭加速度计,从而阻止传感器事件监听器接收新事件.

我也用CyanogenMod RC7.2对它进行了测试,但它也没有用,因为加速度计驱动器是LG的原装.

电子邮件与LG的人力资源部门交换

我发了一封电子邮件给LG P990的开发者,最后得到了一些具体的答案!对于像我这样经历Android问题的人来说,这可能会有很大的帮助.我写了以下问题

你好!我正在开发计算机科学的论文,目前我从加速度计硬件中获取数据.截至目前,我发现加速度计在屏幕关闭时不发送事件,所以即使我从我的一个程序中获取一个唤醒锁,我也可以验证我的程序是否仍在运行(通过LOGcat输出)但是没有加速计事件出来了.我必须调暗屏幕(我买不起,电池耗电太快)才能再次开始接收加速计事件.我也尝试通过本机C代码访问它,注册加速度计事件但结果是相同的,加速度计没有抛出任何值,即使我正在旋转我的设备.所以我想知道我是否可以使用本机代码直接访问硬件,而无需注册到监听器.这可能吗?如果是这样,你能提供一些进一步的建议吗?我非常感谢任何帮助!马丁

对于我收到的回复:

亲爱的马丁,我们得到了Dev的答案.球队.他们说,当手机屏幕关闭时,你无法获得加速度计事件.因为HAL层没有实现sysFS路径来获取加速度计等H/W事件,并且没有公共API来获取事件.谢谢.最好的祝福.(肖恩金)

然后我发回了一封电子邮件,除其他外,我认为这是一个错误,因为在获取唤醒锁时应该有权访问所有硬件:

[...]我问了这个问题,因为我有一些朋友也有Android手机与姜饼版相同,但来自其他手机品牌,其中一些人报告他们在屏幕关闭时从加速度计接收事件.我在一些论坛上看到这个错误 - 我认为这是一个错误,因为当我获得一个Wakelock时,我希望有一些处理正在进行 - 取决于供应商为他们的手机实现的传感器驱动程序.是否有可能更新这些驱动程序或在某些时候纠正此错误?这对我正在进行的工作有很大的帮助[...]

然后我收到了这个答案:

据我所知,来自Dev.团队,那​​不是bug.由于H/W架构,这款手机无限.我们需要重新设计HAL架构和设备驱动程序以支持您的请求.但是,正如您所知,由于缺乏资源,这太困难了.我们正努力帮助您完成所有工作,但我们无法像我提到的那样支持您的请求.(肖恩金)

所以他们显然知道这一点,但他们并没有试图纠正这个问题,因为要么他们认为这不是一个错误 - 我仍然坚信这是一个逻辑缺陷 - 或者他们没有时间/资源来纠正它.

底线 如果您的手机在屏幕关闭时未发送加速度计事件,请尝试更新固件.如果这没有解决,你真的想要做一些严重的黑客攻击,重新实现你的硬件层 - 提示:它可能与libsensors.so有关.

  • 好的我列了一个清单:http://www.saltwebsites.com/2012/android-accelerometers-screen-off (8认同)
  • 感谢马丁提供这个非常完整的信息.我们真正需要的是一个列表,说明哪些手机支持屏幕上的加速计事件,因为人们可能在购买之前需要这些信息(像我一样 - 我需要这个).也许维基,人们可以测试他们的手机并更新列表.在任何地方都有这样的清单吗? (2认同)
  • 惊人的,非常全面的答案.会给出多个赞成:)在某种程度上,您可以通过收听SCREEN_OFF和SCREEN_ON事件,获取新的唤醒锁定并重新启动加速度计服务来解决问题.但同样,它只适用于某些手机. (2认同)

小智 6

我不确定这是否真的会对你有所帮助,但我找到了一个解决办法(不知道如果能帮助节省电池有多好).

使用bash我有一个while循环捕获/sys/devices/virtual/accelerometer/accelerometer/acc_file,当我通过电源按钮关闭屏幕时输出继续,但被冻结.(我的sshd在chroot中运行,因此能够看到它.)

然而,在呼应0 > /sys/devices/platform/msm_fb.196609/leds/lcd-backlight/brightness.屏幕关闭,输出连续.

这是在SGH-T589W上,运行Android版本2.3.6.