简体   繁体   English

即使使用WakeLock,当Droid / Nexus One屏幕关闭时,Accelerometer也会停止提供样品

[英]Accelerometer stops delivering samples when the screen is off on Droid/Nexus One even with a WakeLock

I have some code that extends a service and records onSensorChanged(SensorEvent event) accelerometer sensor readings on Android. 我有一些代码可以扩展服务并在Android上记录onSensorChanged(SensorEvent事件)加速计传感器读数。 I would like to be able to record these sensor readings even when the device is off (I'm careful with battery life and it's made obvious when it's running). 我希望能够记录这些传感器读数,即使设备关闭时(我对电池寿命非常小心,并且在运行时显而易见)。 While the screen is on the logging works fine on a 2.0.1 Motorola Droid and a 2.1 Nexus One. 虽然屏幕上的日志工作正常,但在2.0.1 Motorola Droid和2.1 Nexus One上。

However, when the phone goes to sleep (by pushing the power button) the screen turns off and the onSensorChanged events stop being delivered (verified by using a Log.e message every N times onSensorChanged gets called). 但是,当手机进入休眠状态时(通过按下电源按钮),屏幕关闭, onSensorChanged事件停止传送(通过每隔N次onSensorChanged调用一次Log.e消息进行验证)。

The service acquires a wakeLock to ensure that it keeps running in the background; 该服务获取wakeLock以确保它在后台运行; but, it doesn't seem to have any effect. 但是,它似乎没有任何影响。 I've tried all the various PowerManager. 我已经尝试了各种各样的PowerManager。 wake locks but none of them seem to matter. 唤醒锁,但它们似乎都不重要。

_WakeLock = _PowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
_WakeLock.acquire();

There have been conflicting reports about whether or not you can actually get data from the sensors while the screen is off... anyone have any experience with this on a more modern version of Android (Eclair) and hardware? 关于在屏幕关闭时你是否能真正从传感器获取数据的报道相互矛盾......任何人都对更现代版的Android(Eclair)和硬件有任何经验吗?

This seems to indicate that it was working in Cupcake: http://groups.google.com/group/android-developers/msg/a616773b12c2d9e5 这似乎表明它在Cupcake中工作: http//groups.google.com/group/android-developers/msg/a616773b12c2d9e5

PS: The exact same code works as intended in 1.5 on a G1. PS:完全相同的代码在G1上的1.5中按预期工作。 The logging continues when the screen turns off, when the application is in the background, etc. 当屏幕关闭,应用程序在后台等时,记录继续。

We've deduced this started as of 2.0.1. 我们从2.0.1开始推断出这一点。 It seems to be intentional, perhaps part of the battery life boost that was touted as a feature. 这似乎是有意的,也许是电池寿命提升的一部分被吹捧为一个功能。 We had a working shake to wakeup or unlock on 2.0, then it broke on the update and we haven't been able to get any kind of workaround. 我们有一个工作摇晃唤醒或解锁2.0,然后它打破了更新,我们无法得到任何解决方法。 ;'( It doesn't matter if CPU partial lock is held which is supposed to always prevent CPU from sleeping. From what I've seen logging debug over USB there appears to occasionally be mention of sensor listener changes as sleep happens. ;'(如果保持CPU部分锁定并不总是阻止CPU休眠也没关系。从我看到的通过USB记录调试的情况看来偶尔会提到传感器监听器随睡眠的变化而变化。

A user posted a workaround that he claimed works on the motorola devices - https://sites.google.com/a/bug-br.org.br/android/technical-documents 用户发布了他声称可以在摩托罗拉设备上使用的解决方法 - https://sites.google.com/a/bug-br.org.br/android/technical-documents

I tested the workaround, coming up with the following code from the tutorial and some manual revision (there are a few "bugs" in his tutorial presented code): 我测试了解决方法,提出了教程中的以下代码和一些手动修订(在他的教程中提供了一些“错误”代码):

public class ShakeWakeupService extends Service implements SensorEventListener{
     private Context mContext;
     SensorManager mSensorEventManager;
     Sensor mSensor;

     // BroadcastReceiver for handling ACTION_SCREEN_OFF.
     public BroadcastReceiver mReceiver = new BroadcastReceiver() {

         @Override
         public void onReceive(Context context, Intent intent) {
             // Check action just to be on the safe side.
             if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
                 Log.v("shake mediator screen off","trying re-registration");
                 // Unregisters the listener and registers it again.
                 mSensorEventManager.unregisterListener(ShakeWakeupService.this);
                 mSensorEventManager.registerListener(ShakeWakeupService.this, mSensor,
                     SensorManager.SENSOR_DELAY_NORMAL);
             }
         }
     };

         @Override
         public void onCreate() {
           super.onCreate();
           Log.v("shake service startup","registering for shake");
           mContext = getApplicationContext();
             // Obtain a reference to system-wide sensor event manager.
           mSensorEventManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
             // Get the default sensor for accel
           mSensor = mSensorEventManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
             // Register for events.
           mSensorEventManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);

             // Register our receiver for the ACTION_SCREEN_OFF action. This will make our receiver
             // code be called whenever the phone enters standby mode.
           IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
           registerReceiver(mReceiver, filter);
     }

     @Override
     public void onDestroy() {
        // Unregister our receiver.
         unregisterReceiver(mReceiver);
         // Unregister from SensorManager.
         mSensorEventManager.unregisterListener(this);
     }

     @Override
     public IBinder onBind(Intent intent) {
         // We don't need a IBinder interface.
  return null;
     }

 public void onShake() {
         //Poke a user activity to cause wake?
     }
     public void onAccuracyChanged(Sensor sensor, int accuracy) {
                //not used right now
            }
            //Used to decide if it is a shake
            public void onSensorChanged(SensorEvent event) {
                    if(event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) return;
                  Log.v("sensor","sensor change is verifying");
            }
      }

The workaround works for me, but will not work while I have screebl running, which is a feature a lot of my users really want working in conjunction with what I'm developing. 这个解决方法对我有用,但在我运行screebl时不起作用,这是我的很多用户真正想要与我正在开发的东西一起工作的功能。

Just updated my Nexus One with the FROYO FRF50 ROM that has been kicking around the internets for the last few days, and it seems that sensors now work again when the screen is off if you have a PARTIAL_WAKELOCK. 刚刚使用FROYO FRF50 ROM更新了我的Nexus One,过去几天一直在互联网上徘徊,如果你有一个PARTIAL_WAKELOCK,屏幕关闭时传感器现在可以再次运行。 I don't know if this will make it to the official build, although my understanding is that this is based on an official build that some N1 users received. 我不知道这是否会成为官方版本,虽然我的理解是这是基于一些N1用户收到的官方版本。 So maybe they've changed their minds (once again), and re-enabled the sensors when the phone is locked. 所以也许他们已经改变了主意(再次),并在手机锁定时重新启用了传感器。 Fingers crossed. 手指交叉。

Of course, they could just go and disable them again in 2.2-r1, who knows... 当然,他们可以在2.2-r1再次禁用它们,谁知道......

Using a SCREEN_DIM_WAKE_LOCK worked for me on the HTC EVO.. 在HTC EVO上使用SCREEN_DIM_WAKE_LOCK为我工作..

final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
_WakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "TAG");
_WakeLock.acquire();

It seems that it is a 2.1 firmware issue, it's necessary for me to get this fixed but i'm have to work in all sorts of workarounds to cover all versions. 它似乎是一个2.1固件问题,我需要修复它,但我必须在各种解决方案中工作以涵盖所有版​​本。

I've been putting together a list of phones and firmwares which work / don't work / intermittently work so that we can either test the phone or firmware. 我一直在整理一个工作/不工作/间歇工作的手机和固件列表,以便我们可以测试手机或固件。

http://apprssd.com/2010/09/08/android-onsensorchanged-not-working-when-screen-lock-is-on/ http://apprssd.com/2010/09/08/android-onsensorchanged-not-working-when-screen-lock-is-on/

If you have a new phone you can update the list with, let me know. 如果您有新手机,可以更新列表,让我知道。

There's an alternate solution (sort of) where you keep the screen always turned on using: 还有一种替代解决方案(某种方式),您可以使用以下方法保持屏幕始终处于打开状态:

Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, -1); Settings.System.putInt(getContentResolver(),Settings.System.SCREEN_OFF_TIMEOUT,-1);

But this doesn't prevent the user from forcing the screen to off by pressing the power button and then the sensor event stream stops. 但这并不能阻止用户按下电源按钮强制关闭屏幕,然后传感器事件流停止。 You also need the WRITE_SETTINGS permission for this to work. 您还需要WRITE_SETTINGS权限才能生效。

The workaround above of re-registering for sensor events does not work on the Droid Eris, which runs Android 2.1 and is not expected to ever get an upgrade. 上面重新注册传感器事件的解决方法不适用于运行Android 2.1且预计不会升级的Droid Eris。 I've used the following though which does appear to work. 我已经使用了以下内容,虽然看起来确实有用。 Instead of un-registering and re-registering, this approach turns the screen back on when the user turns it off, although it comes back on dimmed. 这种方法不是取消注册和重新注册,而是在用户将其关闭时重新打开屏幕,尽管它会变暗。 In the following code, handler is just a simple Handler constructed in the Activity (ie, Handler handler = new Handler(); ) and mTurnBackOn is a WakeLock initialized to null. 在下面的代码中,handler只是一个在Activity中构造的简单Handler(即Handler handler = new Handler();)而mTurnBackOn是一个初始化为null的WakeLock。

public BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
            // Turn the screen back on again, from the main thread
            handler.post(new Runnable() {
            public void run() {
            if(mTurnBackOn != null)
                mTurnBackOn.release();

                mTurnBackOn = mPwrMgr.newWakeLock(
                    PowerManager.SCREEN_DIM_WAKE_LOCK |
                        PowerManager.ACQUIRE_CAUSES_WAKEUP,
                    "AccelOn");
                mTurnBackOn.acquire();
            }});
        }
    }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM