Accelerometer SensorEvent时间戳

时间:2011-03-31 13:38:08

标签: android

我目前正在开发一个Android应用程序..我必须记录加速计传感器事件坐标和事件时间。我得到了传感器事件时间戳,如“3497855005850”,但我无法将事件时间戳转换为用户可读的日期时间格式。谢谢提前

如何将SensorEvent时间戳转换为unix时间戳?

7 个答案:

答案 0 :(得分:35)

传感器时间戳实际上是纳秒的正常运行时间,不是系统时间(以纳秒为单位)。请参阅SensorEvent.timestamp to absolute (utc) timestamp?

理论上,您可以使用以下方法将传感器时间戳转换为时间(以毫秒为单位)

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

您甚至可以通过两次(new Date()).getTime()来电调整System.nanoTime()来电,并将它们平均以接近实际偏移量。

然后您可以将传感器时间格式化为日期和时间。

答案 1 :(得分:3)

您可以在onSensorChanged(SensorEvent)功能中设置参考时间变量。

参考当前时间和事件时间。当事件到达时从事件时间中减去传感器指示时间,您将有纳秒的差异。您可以将该差值除以1,000,000添加到当前时间参考,以获得事件时间(以毫秒为单位) 计算此错误可能是一个事件的最大0.5毫秒。您可以通过偶尔更改引用时间来最小化错误。

private long sensorTimeReference = 0l;
private long myTimeReference = 0l;

public void onSensorChanged(SensorEvent event) {
    // set reference times
    if(sensorTimeReference == 0l && myTimeReference == 0l) {
        sensorTimeReference = event.timestamp;
        myTimeReference = System.currentTimeMillis();
    }
    // set event timestamp to current time in milliseconds
    event.timestamp = myTimeReference + 
        Math.round((event.timestamp - sensorTimeReference) / 1000000.0);
    // some code...
}

答案 2 :(得分:1)

我遇到了同样的问题,并使用了ehartwell solution。不过我使用的是System.currentTimeMillis()而不是new Date().getTime()

此外,我发现最大300毫秒的sensorEvent.timeStampSystem.nanoTime()的偏移量大部分是<1}。 200毫秒。根据所需的准确度,您可以忽略这种差异。

如果我使用Boban S. solution,则初始化时的差异是正确的。但是,测量的正确时间和时间不同。估计的测量时间是将来的。

答案 3 :(得分:1)

我看到三种获得Millis(Kotlin)的方法

val millis = Date().getTime() + (event.timestamp - System.nanoTime()) / 1000000L

val millis = System.currentTimeMillis() + (event.timestamp - System.nanoTime()) / 1000000L

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

所有三个结果都相同,但是当我想查看从计算值到当前时间的差异

val diff  = System.currentTimeMillis() - millis

我看到'diff'的值为 -359704905 吗?

Log.d("diff", "" + event.timestamp + " - " + System.nanoTime())
  

差异:541695268300000-181990403666592

     

差异:541695277240000-181990405818592

     

差异:541695286859000-181990411901592

     

差异:541695296139000-181990412584592

     

差异:541695305735000-181990415222592

所以所有建议的解决方案不正确

对我来说,这种简单的方式符合我的需求

override fun onSensorChanged(sensorEvent: SensorEvent?) {
    val millis = System.currentTimeMillis()
}

答案 4 :(得分:1)

https://source.android.com/devices/sensors/hal-interface.html#sensors_event_t
“时间戳记必须与经过的RealtimeNano时钟同步” 所以

$('#submit-btn').on('click', function() {
    if($('#username').val().length < 6) {
        alert("Hey, that username isn't like enough bro");
    }
    else {
        $('form').submit();
    }
});

答案 5 :(得分:0)

因设备而异。它可能基于时代,自启动以来的时间以及CPU唤醒时间。最好的方法是先读取所有三个,然后查看时间戳最接近哪个,然后根据偏移量进行转换。

答案 6 :(得分:0)

SensorEvent#timestamp documentation官方声明:

[event.time是]事件发生的时间(以纳秒为单位)。对于给定的传感器,每个新的传感器事件应使用与SystemClock.elapsedRealtimeNanos()相同的时基单调增加

挑战

  • 某些制造商/设备使用了SystemClock.currentTimeNanos()(例如Nexus 4)。

与设备无关的解决方案:

/**
 * 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
 */
private long eventTimeOffset(final long eventTimeNanos) {
    // Capture timestamps of event reporting time
    final long elapsedRealTimeMillis = SystemClock.elapsedRealtime();
    final long upTimeMillis = SystemClock.uptimeMillis();
    final long currentTimeMillis = System.currentTimeMillis();

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

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

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

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

注册时间延迟

  • 该代码与event.time和触发传感器事件侦听器的时间(注册时间)之间的延迟无关,因为我们仅使用SystemClock来计算偏移量。
  • 如果同步了多个设备的系统时间,则可以在多个设备之间同步传感器数据。(

关于“可能的情况”(请参见代码):

  • 尚不清楚是否有任何制造商将upTime用作event.time。因此,我们抛出异常以查看是否确实发生过这种情况。

  • 如果发生这种情况,并且如果我们计算currentTimeupTime之间的静态偏移,则当设备再次进入(深度)睡眠时,这将导致时间偏移。我们需要为每个非常繁重的事件动态计算偏移量。

  • 如果在设备上发生这种情况,可以使用https://developer.android.com/training/monitoring-device-state/doze-standby#testing_doze_and_app_standby

    进行测试