首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >来自不可靠时钟的设备的数据

来自不可靠时钟的设备的数据
EN

Software Engineering用户
提问于 2016-06-26 20:01:40
回答 3查看 462关注 0票数 2

是否有任何可行的方法来处理来自不可靠时钟设备的数据?

我们在中央服务器上运行着一个数据库系统。最新增加的系统是一堆运行Android的移动条形码扫描仪。我们正在创建一个特定的应用程序,设备将被完全锁定,因此用户只能与该应用程序交互(因此无法访问任何设置)。

总的来说,这是非常简单的,设备将连接使用以太网码头,并下载一个项目列表,以移动与他们的目的地。用户在目的地扫描项目并收集签名以进行传递。一旦连接到码头,任何交付物品的位置将被更新,以及移动的签名和时间戳。

计划是,无论何时连接到码头,应用程序都会从服务器时间设置设备时钟。不幸的是,Android不允许应用程序设置时间( SET_TIME权限只允许系统应用程序使用)。此外,网络是难以置信的锁定,所以我们不能依靠内置的同步,设备只有当停靠在以太网的摇篮时才有网络连接。

因此,考虑到这些设备的时钟可能是任意不正确的,那么当数据上传时,我们是否可以对此进行修正呢?无论何时连接到每个设备,都可以在时钟服务器上保存一个日志。

在许多方面,这个问题可以适用于任何支持脱机的应用程序。您如何处理来自不可靠或不可信时钟的设备的与时间相关的数据?

纠正一个一贯错误的时间并不太困难,但如果考虑到如果电池耗尽,设备可能会完全失去时间,这似乎是完全不可能的。对于不可信的设备也会出现类似的问题--如果用户可以任意更改时钟的话。

有没有对这个问题做过任何研究?

EN

回答 3

Software Engineering用户

回答已采纳

发布于 2016-06-26 22:56:54

实际上,您可以做很多事情来恢复接近大多数事件的实际时间。

Android为您提供了一些有用的工具,特别是在设备完成启动、系统时钟改变和关机即将到来时发送的广播意图。它还为您提供了一种检查自启动(通过调用elapsedRealtime()elapsedRealtimeNanos()获得的)后的实时时间的方法。这是一个系统保证将单调增加的值。诀窍是尽可能多地依赖于这一点,尽可能少地依赖于系统时钟,但同时记录每一个事件。

示例可能更好地解释了这一点,因此,假设您的应用程序记录了这些事件(数字是启动后的实际秒数):

代码语言:javascript
复制
018 Boot #1
200 Scan #1
215 Sync #1; server says it's 03:15:22
247 Scan #2
335 Scan #3
430 Halt #1

在215的同步过程中,很容易发现扫描1发生在外部提供的,大概是可靠的时间03: 15 :22之前15秒。

一些未知的时间会过去,设备会在下次同步之前记录更多的事件:

代码语言:javascript
复制
020 Boot #2
432 Scan #4
606 Scan #5
901 Halt #2

(Another unknown amount of time passes)

016 Boot #3
117 Scan #6
208 Sync #2; Server says it's really 23:05:46

如果您停留在服务器给您的时间215,那么当您回来同步两次启动后,您可以向前工作从同步#1和神圣的扫描2和3发生32和120秒后03:15:22。(但是,您不能对停止1之后发生的事件得出任何结论。)扫描6的方式与扫描1相同;它发生在同步2之前91秒。

这就留下了扫描4和5,这是一个问题,因为在引导/停止周期中没有可靠的时间引用可用于将启动时间编号转换为绝对时间戳。这是你必须转向系统时钟的地方。

如果您使用事件记录系统时间,则可以使用您认为可靠的时间戳,通过查看停止和引导之间的系统时钟差异,向前或向后延伸到没有启动/暂停间隔的启动/停止间隔。

如果开机时的系统时钟大于您在上一次暂停时的记录(或者应用程序安装/升级,也是您应该记录的事件),那么它正确的概率实际上是相当不错的。除了物理篡改,启动其他操作系统负载等,改变时钟时,设备是关闭的是困难的。因为大多数Android设备在电池完全没电之前就关闭了自己,所以通常有足够的能量让时钟持续一段时间。(在写这篇文章时,我启动了一个没有外部电源的设备,该设备没有足够的电池启动。它已经至少三个月没有开机了,由于无法访问移动或WiFi网络,时钟离实际时间只有几分钟。)

如果时钟显示上次日志事件之前的启动时间,则无法可靠地恢复在该启动/暂停间隔期间进行扫描的时间。你对这些扫描所做的是一个决策。

票数 9
EN

Software Engineering用户

发布于 2016-06-26 22:15:31

一种简单(但近似)的方法是在每次同步时记录每个设备的偏移量。

将数据插入主数据库时,请使用设备最近的偏移量值来调整记录的时间。

如果设备上没有可靠的参考时钟,甚至不可能保证同一设备记录的两个操作仅使用一个时钟值以特定顺序进行。

票数 1
EN

Software Engineering用户

发布于 2016-06-27 08:43:40

最后,如果我没有误解你,你会遇到以下情况:

  • Android设备的时钟设置为可能是随机/错误的时间。
  • 在他们的码头(可能在晚上或早上)部署他们时,没有其他网络连接。

因此,我假设唯一未知的值是本地设备时钟与实际时间之间的时间偏移。

我试着使用实际时间和设备时间之间的偏移来确定实时时间戳--本质上是Harry的建议:

  • 因此,无论何时停靠设备,它都可以请求当前的实际时间。假设现在是早上6:30
  • 这时,设备的内部时钟设置为上午8:00。
  • 这现在允许我们确定两次之间的偏移量,在这种情况下是+1:30。
  • 因此,如果一个客户在上午10:10 (设备时间)收到他们的包裹,我们可以使用先前确定的偏移量来知道包裹实际上是在上午8:40 (1:30“早到”)到达的。
  • 当然,这取决于实现是将时间存储在设备时间还是实际时间。
  • 请注意,我们完全忽略日期。如果其中一些旅行时间超过24小时,你也必须考虑到这一点。

但是,Android应该能够使用NTP时间服务器同步系统的时间。即使用户无法打开时钟应用程序,只要有网络连接,就应该在后台同步。因此,整个问题实际上可能不是一个问题。

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/323315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档