Skip to content Skip to sidebar Skip to footer

Accelerometer Sensorevent Timestamp

Im currently working on a android application.. I have to log the accelerometer sensor event coordinate with event time. I got the sensor event timestamp like '3497855005850' but i

Solution 1:

The sensor timestamp is actually nanoseconds of uptime, not system time in nanoseconds. See SensorEvent.timestamp to absolute (utc) timestamp?.

In theory, you can convert sensor timestamp to time in milliseconds using:

long timeInMillis = (newDate()).getTime() 
                    + (sensorEvent.timestamp - System.nanoTime()) / 1000000L;

You could even bracket the (new Date()).getTime() call with two System.nanoTime() calls and average them to get closer to the actual offset.

Then you can format the sensor time as date and time.

Solution 2:

You can set referent time variables in your onSensorChanged(SensorEvent) function. Reference for current time and event time. When event arrives subtract sensor referent time from event time and you will have difference in nanoseconds. You can add that difference divided by 1,000,000 to current time reference to get event time in milliseconds. Error with calculating this can be max 0.5 milliseconds for one event. You can minimize error by changing referent times occasionally.

privatelong sensorTimeReference = 0l;
privatelong myTimeReference = 0l;

publicvoidonSensorChanged(SensorEvent event) {
    // set reference timesif(sensorTimeReference == 0l && myTimeReference == 0l) {
        sensorTimeReference = event.timestamp;
        myTimeReference = System.currentTimeMillis();
    }
    // set event timestamp to current time in millisecondsevent.timestamp = myTimeReference + 
        Math.round((event.timestamp - sensorTimeReference) / 1000000.0);
    // some code...
}

Solution 3:

The official SensorEvent#timestampdocumentation states:

[event.time is] The time in nanoseconds at which the event happened. For a given sensor, each new sensor event should be monotonically increasing using the same time base as SystemClock.elapsedRealtimeNanos().

Challenge

  • Some manufacturers/devices use the SystemClock.currentTimeNanos() instead (e.g. Nexus 4).

Device-independent solution:

/**
 * Calculates the static offset (ms) which needs to
 *  be added to the `event.time` (ns) to get the Unix
 *  timestamp of the event.
 *
 * @param eventTimeNanos the {@code SensorEvent.time} to be used to determine the time offset
 * @return the offset in milliseconds
 */privatelongeventTimeOffset(finallong eventTimeNanos){
    // Capture timestamps of event reporting timefinallong elapsedRealTimeMillis = SystemClock.elapsedRealtime();
    finallong upTimeMillis = SystemClock.uptimeMillis();
    finallong currentTimeMillis = System.currentTimeMillis();

    // Check which timestamp the event.time is closest to the event.timefinallong eventTimeMillis = eventTimeNanos / 1_000_000L;
    finallong elapsedTimeDiff = elapsedRealTimeMillis - eventTimeMillis;
    finallong upTimeDiff = upTimeMillis - eventTimeMillis;
    finallong currentTimeDiff = currentTimeMillis - eventTimeMillis;

    // Default case (elapsedRealTime, following the documentation)if (Math.abs(elapsedTimeDiff) <= Math.min(Math.abs(upTimeDiff), Math.abs(currentTimeDiff))) {
        finallong bootTimeMillis = currentTimeMillis - elapsedRealTimeMillis;
        return bootTimeMillis;
    }

    // Other seen case (currentTime, e.g. Nexus 4)if (Math.abs(currentTimeDiff) <= Math.abs(upTimeDiff)) {
        return0;
    }

    // Possible case, but unknown if actually used by manufacturers (upTime)thrownewIllegalStateException("The event.time seems to be upTime. In this case we cannot use a static offset to calculate the Unix timestamp of the event");
}

Registration time delay

  • This code is independent of the latency between the event.time and the time at which the sensor event listener is triggered (registration time) as we only use the SystemClock to calculate the offset.
  • This allows to synchronize the sensor data between multiple devices if their system time is synchronized (there are apps for this).

Regarding "Possible Case" (see code):

  • It's unknown if any manufacturer actually uses the upTime as event.time. Thus, we throw an exception to see if this actually ever happens.

  • If this happens and if we calculate a static offset between currentTime and upTime this would lead to time shifts when the device is in (deep) sleep again. We would need to calculate the offset dynamically for each event which is quite heavy.

  • If this happens on devices this could be tested using: https://developer.android.com/training/monitoring-device-state/doze-standby#testing_doze_and_app_standby

Solution 4:

https://source.android.com/devices/sensors/hal-interface.html#sensors_event_t "timestamp must be synchronized with the elapsedRealtimeNano clock" so

val timeInMills = System.currentTimeMillis() + (event.timestamp - SystemClock.elapsedRealtimeNanos()) / 1000000

Solution 5:

I had the same problem and used ehartwell's solution. However I used System.currentTimeMillis() instead of new Date().getTime().

Furthermore I found that there is an offset of sensorEvent.timeStamp and System.nanoTime() of maximal 300 ms, mostly < 200 ms. Depending on the needed accuracy you can ignore this difference.

If I use Boban S. solution, the difference is correct at the initialisation. However, the correct time and the time of the measurements diverge. The estimated time of the measurements is in the future.

Post a Comment for "Accelerometer Sensorevent Timestamp"