屏幕关闭时Android加速计不工作

我正在为我的计算机科学期末论文开发一个应用程序,我需要收集和记录加速度计数据。我需要买一整天,所以电池严重不足(例如,我不能一直开着屏幕)。此外,这不是一个面向市场的应用程序,因此如果需要,可以进行一些严重的黑客攻击,甚至是低级C/C++编码

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

那么发生的情况是:
当您在服务中注册android Accelerator sensor的事件侦听器时,它可以正常工作,直到屏幕关闭。我已经尝试在一个服务、一个IntentService上注册eventListener,并尝试获取WakeLocks。关于wakelocks,我可以通过观察LOGcat输出来验证服务是否仍在运行,但加速度计似乎已进入睡眠模式。一些链接中提供的解决方法之一是使用IntentService的线程定期注销和重新注册事件侦听器,如下面的代码段所示

同步私有静态PowerManager.WakeLock getLock(上下文){
if(lockStatic==null){
PowerManager mgr=(PowerManager)context.getSystemService(context.POWER\u服务);
lockStatic=mgr.newWakeLock(PowerManager.PARTIAL\u WAKE\u LOCK,名称);
lockStatic.setReferenceCounted(true);
}
返回(锁定静态);
}
@凌驾
受保护的手部内容无效(意图){
sensorManager=(sensorManager)getSystemService(传感器服务);
sensorManager.UnregistereListener(此);
sensorManager.registerListener(这是sensorManager.getDefaultSensor(Sensor.TYPE\u Accelerator),sensorManager.Sensor\u DELAY\u NORMAL);
已同步(此){
布尔运行=真;
while(运行){
试一试{
等待(1000);
getLock(AccelerometerService.this).acquire();
sensorManager=(sensorManager)getSystemService(传感器服务);
sensorManager.UnregistereListener(此);
sensorManager.registerListener(这是sensorManager.getDefaultSensor(Sensor.TYPE\u Accelerator),sensorManager.Sensor\u DELAY\u NORMAL);
Log.d(“加速计服务”,“滴答声!”);
}捕获(例外e){
运行=错误;
Log.d(“加速计服务”,“中断;原因:”+e.getMessage());
}
}
}
}
@凌驾
传感器更改时的公共无效(传感器事件){
Log.d(“接收到加速计事件”,“xyz:+事件.值[0]+”,“+事件.值[1]+”,“+事件.值[2]);
}

这确实使得每次我们注销/注册侦听器时都会调用onSensorChange。问题是接收到的事件总是包含相同的值,而不管我如何晃动设备

所以,基本上我的问题是:(请容忍我,我快结束了:p)

  1. 是否可以在不注册事件侦听器的情况下对加速计硬件进行低级别访问(C/C++方法)

  2. 是否有其他解决方法或黑客

  3. 如果固件3.0及以上版本仍然存在问题,任何拥有更先进手机的人都可以测试一下吗

[更新]

不幸的是,这似乎是一些手机的一个缺陷。更多详情请参见我的答案。

基本上,这是我手机的问题。其他用户报告说,这也发生在他们的手机上,来自不同品牌,但安卓版本相同。其他人根本没有问题——这强烈表明这不是android股票版本的问题,而是每个公司的硬件驱动程序实现的问题

我需要提供恒定的加速计数据,不能让加密狗为我测量这些数据-我有一个带蓝牙和加速计的Arduino,所以我可以实现这个解决方案。因此,我决定暂时解决我的手机问题的办法是打开屏幕(调暗),忽略电池消耗。稍后,我将使用另一款屏幕关闭的android手机进行电池使用测试

有关该错误的更多信息

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

我也用CyanogenMod RC7.2测试了这一点,但它也不起作用,因为加速计驱动器是LG的原创产品

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

我给LG P990的开发者发了一封电子邮件,最后得到了一些具体的答案!这对像我这样的人来说可能会有很大的帮助,因为他们在Android上遇到了这些问题。我写了下面的问题

你好!!我正在写计算机科学的论文,目前我
我正在从加速计硬件获取数据。到现在为止,我发现了
当屏幕关闭时,加速计不会发送事件,因此
即使我从我的程序中获取唤醒锁,我也可以
确认我的程序仍在运行(通过LOGcat输出),但没有
加速计事件出来了。我必须调暗我的屏幕
负担不起,电池耗尽太快)无法开始接收
又是一次重大事件。我还尝试通过本机C访问它
代码,在加速计事件上注册,但结果是
同样,加速度计没有抛出任何值,即使我
旋转我的设备。所以我想知道我是否可以直接进入
到硬件,使用本机代码,无需注册到
听众。这可能吗?如果是的话,你能再给我一些吗
劝告我将非常感谢任何帮助!马丁

对于我收到的回复:

亲爱的Martin,我们收到了开发团队的答复。他们说你
手机屏幕关闭时无法获取加速计事件。因为
HAL层没有实现sysFS路径来获取H/W事件,例如
并且没有公共API来获取事件。非常感谢。最好的
当做(肖恩·金)

然后我发回了一封电子邮件,其中说,我认为这是一个bug,因为在获取唤醒锁时,应该可以访问所有硬件:

[…]我问这个问题是因为我有一些朋友也有
Android手机与姜饼版本相同,但来自其他
手机品牌,其中一些报告称他们从
当屏幕关闭时,加速度计将显示。我读了一些书
论坛,这个bug -我认为它是一个错误,因为当我获得一个
Wakelock我希望有一些处理正在进行-取决于
供应商为其手机实现的传感器驱动程序。是
这些驱动程序是否有可能更新,或者是否会更新
在某个时候可以纠正错误吗?这将极大地帮助我的工作
正在进行的工作[……]

然后我得到了这个答案:

据开发团队所知,这不是bug。这是一个无限的过程
这款手机采用了H/W结构。我们需要重新设计HAL
支持您的请求的体系结构和设备驱动程序。但是,正如你所说
知道由于缺乏资源,这太难了。我们正在努力
我们会尽全力帮助你,但我们不能像我一样支持你的请求
提到。(肖恩·金)

因此,他们显然知道这一点,但没有试图纠正这一点,因为要么他们不认为这是一个错误——我仍然坚信这是一个逻辑缺陷——要么他们没有时间/资源来纠正它

底线
如果您的手机在屏幕关闭时不发送加速计事件,请尝试更新固件。如果这不能解决问题,并且你真的想进行一些严重的黑客攻击,那么重新实现你的硬件层-提示:这可能与libsensors.so有关

发表评论