1

For my project i've created a class that uses the Sensors of the users device to detect north. I only need to get an update every second, and hopefully by making the delay longer save some battery, but I cant get the delay working. What i have:

mAcceleroSensor = mSensorManagerAccelero.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
mMagneticSensor = mSensorManagerMagnetic.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
// Tried to set normal values like SensorManager.SENSOR_DELAY_NORMAL
// and numbers like 100 - 100.000. 1.0000.0000 
// (without the dots only here to make it readable here).
mSensorManagerAccelero.registerListener(this, mAcceleroSensor, 50000000);
mSensorManagerMagnetic.registerListener(this, mMagneticSensor, 50000000);

Everything works except the delay it almost looks like its updated live. I have used code similair to https://stackoverflow.com/a/23060896/1667868 with some minour changes.

Note: the minimum api version I use is 14

Community
  • 1
  • 1
Sven van den Boogaart
  • 11,833
  • 21
  • 86
  • 169

1 Answers1

2

The documentation for SensorManager.registerListener(SensorEventListener listener, Sensor sensor, int samplingPeriodUs):

The events will be delivered to the provided SensorEventListener as soon as they are available. To reduce the power consumption, applications can use registerListener(SensorEventListener, Sensor, int, int) instead and specify a positive non-zero maximum reporting latency.

Whilst the sensor's readings are sampled at the given interval, the reporting interval in that method is not specified causing the callback to be called rapidly as soon as a reading is available. Use the alternative method mentioned in the documentation as such:

 mSensorManagerAccelero.registerListener (this, mAcceleroSensor, 1000000, 1000000)

to get it to report at about once at second (you can manually adjust the sampling rate as needed). This would also help with power usage.

Note the documentation claims the final argument maxReportLatencyUs is the:

Maximum time in microseconds that events can be delayed before being reported to the application.

meaning that it could potentially still report faster than 1 second. If you want user's to see consistent smooth 1 second updates, consider saving results to a averaging buffer and updating the UI once per second.

initramfs
  • 8,275
  • 2
  • 36
  • 58
  • the minimum api versio for registerListener (this, mAcceleroSensor, 1000000, 1000000) is 19, im currently using 14 to support android 4 – Sven van den Boogaart May 10 '15 at 16:57
  • 1
    @SvenB Oh well, given that even the documentation says to use the constants and that `samplingPeriodUs` is `only a hint to the system.` And that `Events may be received faster or slower than the specified rate. Usually events are received faster.` (directly from the documentation), I'd suggest you take the approach of caching the results in an averaging buffer (or LinkedList) and compute the average every second before sending to the UI for a more consistent experience. You can also write conditional code to call the 4 arg method if the device's SDK level is 19+ – initramfs May 10 '15 at 17:02