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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…