Gabriel Morin Gabriel Morin - 2 months ago 17
Android Question

SensorEventListener temporarily not working

I've implemented SensorEventListener in my MainActivity, and it works quite well, i'd even say most of the time very well.

But weirdly, sometimes it completely stops working, I need to shake it in every direction for 5-10 seconds and it's magically back on.
It seems to be after the phone as idle/asleep for a long time.

I did implemented the register/unregister on onResume/onPause.

Here is my code, mostly coming from stackoverflow:

SensorManager sensorManager;

private float accel; // acceleration apart from gravity
private float accelCurrent; // current acceleration including gravity
private float accelLast; // last acceleration including gravity
private static final float SHAKE_THRESHOLD = 12.f;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initSensor();
}


private void initSensor() {
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
registerSensor();
}

private void registerSensor() {
HandlerThread handlerThread = new HandlerThread(HANDLER_THREAD_NAME_SENSOR);
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL, handler);
accel = 0.00f;
accelCurrent = SensorManager.GRAVITY_EARTH;
accelLast = SensorManager.GRAVITY_EARTH;
}

@Override
protected void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}

@Override
protected void onResume() {
super.onResume();
registerSensor();
}

@Override
public void onSensorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
accelLast = accelCurrent;
accelCurrent = (float) Math.sqrt((double) (x*x + y*y + z*z));
float delta = accelCurrent - accelLast;
accel = accel * 0.9f + delta; // perform low-cut filter
//Log.d(TAG, ">>> ALL shake accel = "+ accel);
if (accel > SHAKE_THRESHOLD) {
Log.d(TAG, "shake accel = "+ accel);
runOnUiThread(new Runnable() {
@Override
public void run() {
// Do stuffs in the UI
}
});

}
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// Nothing do to here
}

Answer

It was fixed by changing the sensor delay to SensorManager.SENSOR_DELAY_FASTEST; The registration now looks like :

// Global
private static final String HANDLER_THREAD_NAME_SENSOR = "sensorThread";

// ...Registration
HandlerThread handlerThread = new HandlerThread(HANDLER_THREAD_NAME_SENSOR);
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());
mSensorManager.registerListener(this,
                    mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                    SensorManager.SENSOR_DELAY_FASTEST,
                    handler);
Comments