屏幕关闭时,Android 加速度计不工作 [英] Android accelerometer not working when screen is turned off

查看:27
本文介绍了屏幕关闭时,Android 加速度计不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的计算机科学毕业论文开发一个应用程序,我需要收集和记录加速度计数据.我需要一整天的时间来获取它,因此电池受到严重限制(例如,我不能让屏幕保持开启状态).此外,这不是面向市场的应用程序,因此如果需要,进行一些严重的黑客攻击,甚至是低级别的 C/C++ 编码也是完全可以接受的.

I'm developing an application for my final thesis on computer science, and I need to collect and log accelerometer data. I need to acquire it for a whole day long, so there are serious battery constraints (for instance, I cannot leave the screen on). Also, this isn't a market targeted application, so it is pretty acceptable to do some serious hacking, even low level C/C++ coding, if required.

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

It is well known that on many devices the listeners for accelerometer events stop generating events when screen goes off (some links regarding this problem: 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). I have thoroughly searched for some alternatives, some of them include workarounds that do not work for my device (LG P990, stock ROM).

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

So what happens is this: When you register an event listener for android accelerometer sensor in a Service, it works fine until the screen is turned off. I have already tried to register the eventListener on a Service, on an IntentService, tried to acquire WakeLocks. Regarding wakelocks, I can verify that the service is still running watching the LOGcat output, but it seems the accelerometer is put into sleep mode. One of the workarounds presented in some of the links is to unregister and re-register the event listener periodically using the thread of an IntentService like in this code snippet bellow

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.问题是接收到的事件总是包含相同的值,无论我如何摇动设备.

which indeed makes the onSensorChange be called every time we unregister/register the listener. The problem is that the event received contains always the same values, regardless of me shaking the device.

所以,基本上我的问题是:(请耐心等待,我快要完成了:P)

So, basically my questions are: ( bear with me, I'm almost finishing :P )

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

  1. is it possible to have low level access (C/C++ approach) to the accelerometer hardware WITHOUT registering to an event listener?

还有其他解决方法或黑客吗?

is there any other workaround or hack?

谁能用最新的手机测试一下固件 3.0 及以上版本问题是否仍然存在?

could anyone with a more up-to-date phone kindly test if the problem persists in firmware 3.0 and above?

[更新]

不幸的是,这似乎是某些手机的错误.我的回答中有更多详细信息.

推荐答案

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

Basically, it is a problem with my phone. Other users have reported this also happens with their phones, from different brands but same Android version. Other persons have no problem at all - strongly indicating that this is not a problem with the stock version of android but from the implementations of each company for their hardware drivers.

我需要提供恒定的加速度计数据,但无法使用加密狗为我测量这些数据 - 我有一个带蓝牙和加速度计的 Arduino,所以我可以实施这个解决方案.所以我决定我手机的临时解决方案是让屏幕打开(变暗)并忽略电池消耗.稍后我将使用另一部可在屏幕关闭的情况下使用的 Android 手机执行电池使用测试.

I need constant accelerometer data delivered and cannot have a dongle measure this data for me - I have an Arduino with Bluetooth and accelerometer, so I could have implemented this solution. So I decided that the temporary solution for my cellphone was to let the screen on (dimmed) and ignore battery consumption. Later on I will perform the tests for battery usage using another android phone which works with the screen turned off.

有关错误的更多信息

我进行了更多研究,并发现了其他 Android 用户的报告,我想我可能了解正在发生的事情.包含手机传感器驱动程序的库 libsensors.so 不是由 Google 开发的,而是由每个手机供应商开发的——当然,因为每个手机都有自己特定的硬件.Google 只提供了一个 C 头文件,以便开发人员知道他们必须实现什么.在这些驱动程序的某些实现中,开发人员只需在屏幕熄灭时关闭加速度计,从而阻止传感器事件侦听器接收新事件.

I've researched some more and found reports from other Android users and I think maybe I understand what is happening. The library libsensors.so which has the drivers for the phone sensors is not developed by Google but by each cellphone vendor - of course, because each cellphone has its own specific hardware. Google only provides a C header file so that the developers know what they have to implement. On some implementations for these drivers, the developers simply turn the accelerometer off when the screen goes off, thus preventing the sensor event listener to receive new events.

我也用 CyanogenMod RC7.2 对此进行了测试,但它也不起作用,因为加速度计驱动程序来自 LG.

I also tested this with CyanogenMod RC7.2 but it did not work either, because accelerometer drivers are original from LG.

与 LG 人力资源部的邮件往来

我给 LG P990 的开发者发了一封电子邮件,终于得到了一些具体的答复!这可能对像我这样在 Android 上遇到这些问题的人有很大帮助.我写了以下问题

I sent an e-mail to the developers of the LG P990 and finally got some concrete answers! This may be of great help to some people like me that are experiencing these issues with Android. I wrote the following question

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

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

对于我收到的回复:

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

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 then sent an e-mail back, saying among other things, that I considered this a bug, since one should have access to all the hardware when acquiring a wake lock:

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

[...] 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 [...]

然后我收到了这个答案:

And then I received this answer:

据我所知,Dev.团队,这不是错误.那是无限的这款手机因为硬件架构.我们需要重新设计 HAL架构和设备驱动程序来支持您的请求.但是,正如你知道由于缺乏资源,这太难了.我们正在努力尽我们所能帮助您,但我们无法支持您的请求,因为我提及.(肖恩·金)

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)

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

So they apparently know about this but are not trying to correct this because either they don't think it is a bug - which I still strongly believe is a logical flaw - or they don't have the time/resources to correct it.

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

Bottom line If you have a cellphone that does not send accelerometer events with the screen off, try updating your firmware. If this does not solve and you really want to do some serious hacking, re implement your hardware layer - hint: it's probably something to do with libsensors.so.

这篇关于屏幕关闭时,Android 加速度计不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆