- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在为我关于计算机科学的期末论文开发一个应用程序,我需要收集和记录加速度计数据。我需要一整天的时间来获取它,因此存在严重的电池限制(例如,我无法让屏幕保持开启状态)。此外,这不是针对市场的应用程序,因此如果需要,可以进行一些严重的黑客攻击,甚至是低级 C/C++ 编码。
众所周知,在许多设备上,加速度计事件的监听器会在屏幕关闭时停止生成事件(有关此问题的一些链接:http://code.google.com/p/android/issues/detail?id=3708,Accelerometer stops delivering samples when the screen is off on Droid/Nexus One even with a WakeLock)。我已经彻底搜索了一些替代方案,其中一些包括不适用于我的设备的解决方法(LG P990,库存 ROM)。
所以会发生这样的事情:当您在服务中为 android 加速度计传感器注册事件监听器时,它可以正常工作,直到屏幕关闭。我已经尝试在服务上注册 eventListener,在 IntentService 上尝试获取唤醒锁。关于唤醒锁,我可以通过观察 LOGcat 输出来验证服务是否仍在运行,但加速度计似乎已进入休眠模式。一些链接中提供的解决方法之一是使用 IntentService 的线程定期取消注册和重新注册事件监听器,如下面的代码 fragment 所示
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]);
}
这确实使得每次我们注销/注册监听器时都会调用 onSensorChange。问题是接收到的事件总是包含相同的值,不管我摇晃设备。
所以,基本上我的问题是:(请耐心等待,我快完成了:P)
是否可以在不注册事件监听器的情况下对加速度计硬件进行低级别访问(C/C++ 方法)?
还有其他解决方法或破解方法吗?
如果问题在固件 3.0 及更高版本中仍然存在,任何拥有更新手机的人都可以测试一下吗?
[更新]
不幸的是,这似乎是某些手机的错误。我的回答中有更多详细信息。
最佳答案
基本上是我手机的问题。其他用户报告说,这也发生在他们的手机上,来自不同品牌但相同的 Android 版本。其他人完全没有问题 - 强烈表明这不是 android 的股票版本的问题,而是每个公司对其硬件驱动程序的实现。
我需要提供恒定的加速度计数据,并且无法让加密狗为我测量这些数据 - 我有一个带蓝牙和加速度计的 Arduino,所以我可以实现这个解决方案。所以我决定我手机的临时解决方案是让屏幕亮起(变暗)并忽略电池消耗。稍后我将使用另一部关闭屏幕的安卓手机进行电池使用测试。
有关该错误的更多信息
我进行了更多研究,并发现了其他 Android 用户的报告,我想也许我了解正在发生的事情。包含手机传感器驱动程序的库 libsensors.so 不是由 Google 开发的,而是由每个手机供应商开发的——当然,因为每个手机都有自己特定的硬件。 Google 只提供了一个 C 头文件,以便开发人员知道他们必须实现什么。在这些驱动程序的某些实现中,开发人员只需在屏幕关闭时关闭加速度计,从而阻止传感器事件监听器接收新事件。
我也用 CyanogenMod RC7.2 对此进行了测试,但它也不起作用,因为加速度计驱动程序是 LG 原装的。
与 LG 人力资源部交流的电子邮件
我给 LG P990 的开发者发了一封邮件,终于得到了一些具体的答复!这可能对像我这样在 Android 上遇到这些问题的人有很大帮助。我写了以下问题
Hello! I am developing my thesis in computer science and currently I am fetching data from accelerometer hardware. As of now, I found out that the accelerometers do not send events when the screen is off, so even when I grab a wakelock from within one of my programs, I can verify that my program is still running (through LOGcat output) but no accelerometer event comes out. I have to dim my screen on (which I cannot afford, the battery drains too fast) to start receiving accelerometer events again. I also tried accessing it through native C code, registering on the accelerometer events but the result was the same, the accelerometer did not throw any values, even though I was rotating my device. So I was wondering if I could have direct access to the hardware, with native code, without having to register to a listener. Is this possible? If so, could you kindly give some further advice? I would appreciate very much any help! Martin
对于我收到的回复:
Dear Martin, We received the answer from Dev. Team. They said that you can’t get accelerometer event while your phone screen is off. Because HAL layer didn’t implement sysFS path to get H/W event such as accelerometer and there is no public API to get event. Thank you. Best Regards. (Sean Kim)
然后我回了一封电子邮件,说我认为这是一个错误,因为在获取唤醒锁时应该可以访问所有硬件:
[...] I asked this question because I have some friends that also have Android phones with the same gingerbread version but from other cellphone brands, and some of them reported they receive events from the accelerometers when the screen is turned off. I read on some forums that this bug - I consider it a bug, since when I acquire a Wakelock I would expect to have some processing going on - depends on the sensor drivers that the vendors implement for their cellphones. Is there any possibility that these drivers can be updated or will this bug be corrected at some point? This would help me enormously with my ongoing work [...]
然后我收到了这个答案:
In my knowledge from Dev. Team, That isn’t bug. That is a limitless of this phone because of H/W architecture. We need to redesign the HAL architecture and device driver to support your request. But, as you know that is too difficult due to lack of resource. We are trying to help you with our all efforts but we cannot support your request as I mentioned. (Sean Kim)
所以他们显然知道这一点,但并没有试图纠正这一点,因为要么他们不认为这是一个错误——我仍然坚信这是一个逻辑缺陷——要么他们没有时间/资源来纠正它。
底线如果您的手机在屏幕关闭的情况下不发送加速度计事件,请尝试更新您的固件。如果这不能解决并且您真的想进行一些严重的黑客攻击,请重新实现您的硬件层 - 提示:这可能与 libsensors.so 有关。
关于屏幕关闭时Android加速度计不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9982433/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!