Accelerometer stops delivering samples when the screen is off on Droid/Nexus One even with a WakeLock
Solution 1
We've deduced this started as of 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. ;'( 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.
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
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.
Solution 2
Using a SCREEN_DIM_WAKE_LOCK
worked for me on the HTC EVO..
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
_WakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "TAG");
_WakeLock.acquire();
Solution 3
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. 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. 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...
Related videos on Youtube
William
Updated on April 16, 2022Comments
-
William about 2 years
I have some code that extends a service and records onSensorChanged(SensorEvent event) accelerometer sensor readings on Android. 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.
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 timesonSensorChanged
gets called).The service acquires a wakeLock to ensure that it keeps running in the background; but, it doesn't seem to have any effect. I've tried all the various 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?
This seems to indicate that it was working in Cupcake: http://groups.google.com/group/android-developers/msg/a616773b12c2d9e5
PS: The exact same code works as intended in 1.5 on a G1. The logging continues when the screen turns off, when the application is in the background, etc.
-
Roman Nurik over 14 yearsTrack this issue here: code.google.com/p/android/issues/detail?id=3708
-
mylock about 14 yearsI've updated answer below with a workaround that we've found seems effective on the motorola 2.0.1 devices. I will also report back as soon as 2.1 is available of any impact on the issue
-
Artem over 13 yearsNew tracker for this issue -- still broken in 2.2 -- code.google.com/p/android/issues/detail?id=11028
-
Fletch almost 12 yearsList of phones which do/don't work: saltwebsites.com/2012/android-accelerometers-screen-off
-
ChuongPham about 10 yearsIssue 3708 posted by Roman Nurik above is still unfixed. Sadly, there's no universal workaround that will work for all affected Android devices.
-
-
pableu almost 14 yearsSmall update to this: They didn't disable it in 2.2 final. The sensors work while the screen is off the final 2.2 build (FRF91) on my Nexus One.
-
Ashish over 12 yearsJust too add... This workaround will be more resource intensive as the screen will be left in dimmed out state. After much searching around, it seems that this problem is still unsolved on later android OS versions...
-
Jameson about 12 yearsThanks for this; combined with a PARTIAL_WAKE_LOCK, the re-registration technique mostly worked for me. But I had to put the re-registration bits in a timed execution thread, s.t. it happens after all the SCREEN_OFF activities settle down. Details here: nosemaj.org/android-persistent-sensors
-
Sharanabasu Angadi over 10 yearsThanks for answer @mylock