Android GPS时间快了15秒

Irc*_*ver 5 gps android

我在我的同步应用程序的时间与android.location.Location"s法getTime()里面onLocationChanged方法调用.问题是在某些设备上结果是正确的,在某些设备上快15秒.据我所知,这是因为GPS时间和UTC差异.

如何检查设备是否知道这种差异?我需要我的应用程序在所有设备上同时显示.

我不能使用网络同步作为解决方案.

baz*_*zza 5

这里可能有几个不同的因素在起作用。

全球定位系统和协调世界时

首先,正如您指出的那样,GPS 时间与 UTC 时间不同。GPS 有一条消息,用于通告与 UTC 的当前偏移量,请参见此处。可能不是所有手机中的 GPS 芯片都关注它,或者在您要求 GPS 时间数据的那一刻还没有收到 GPS 偏移消息。

除非 Android API 支持发现这种情况,否则您将不得不自己解释 NMEA 句子(我不知道 Android 是否提供它们),即使如此,这也取决于制造商的决定放入这些句子中。

根据此 PDF 文件,GPS 接收器接收完整的年历数据可能需要长达半小时的时间。年历包含当前的 GPS/UTC 偏移量。

我的猜测是,因为移动 GPS 芯片是围绕 AGPS(辅助 GPS)构建的,所以他们可能希望从蜂窝网络中获取 GPS 年历数据,并且在为自己保留或接收年历数据方面可能不太聪明。

因此,如果您不在 WiFi 和移动电话网络的范围内(您说您无法使用网络同步来获取一天中的时间...),可能需要 12.5 分钟到半小时,手机的 GPS 芯片才开始为您提供UTC 时间而不是 GPS 时间。

开启手机的 GPS 芯片需要很长时间。我猜他们通常没有通过操作系统启动足够长的时间来接收整个年历。

如果这确实是您问题的原因,那么您可能会陷入困境。GPS 年历数据不会经常更改 AFAIK,因此您可以自己缓存它并以某种方式将其提供给 OS/GPS,而不是从本地蜂窝基站读取它。不过,这听起来非常低级,我怀疑 Android 是否支持这种年历注入(对于恶意软件来说,这是一个可怕的拒绝服务机会......)。

时钟漂移

另一个不太可能的因素是移动设备不一定像台式机那样运行 NTP 客户端。大多数 Linux 桌面发行版都安装了一个 NTP 客户端,该客户端不断在后台运行,使本地时钟与某处的某个 NTP 服务器保持同步。手机(包括 AFAIK Android)通常不需要那么高的时间精度,因此为了节省电池寿命,它们很少校正时钟,因此可能会积累大量漂移。但是,如果它变得糟糕到 15 秒,我会感到惊讶,所以这可能不是由于这个原因。


Chr*_*ian 4

根据文档

公共长getTime()

Return the UTC time of this fix, in milliseconds since January 1,
1970.

Note that the UTC time on a device is not monotonic: it can jump
forwards or backwards unpredictably. So always use
getElapsedRealtimeNanos() when calculating time deltas.

On the other hand, getTime() is useful for presenting a human readable
time to the user, or for carefully comparing location fixes across
reboot or across devices.

All locations generated by the LocationManager are guaranteed to have
a valid UTC time, however remember that the system time may have
changed since the location was generated. 
Run Code Online (Sandbox Code Playgroud)

退货

time of fix, in milliseconds since January 1, 1970.
Run Code Online (Sandbox Code Playgroud)

您尝试过getElapsedRealtimeNanos() 吗?

要将其转换为日期,请使用

Date date = new Date(System.currentTimeMillis() 
                   - SystemClock.elapsedRealtime() 
                   + location.getElapsedRealtimeNanos());
Run Code Online (Sandbox Code Playgroud)