Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different values for nano time in different sensor data. How to figure them out?

Since the latest Android update (v. 8), I realized a very strange behavior while trying to read sensors. More specifically, I am speaking about WiFi and Cell Towers. Here are two examples:

While I read WiFi access point information data and try to convert accessPoint.timestamp to an absolute timestamp using this code:

long timeInMillis = System.currentTimeMillis() + ((accessPoint.timestamp * 1000L -
                SystemClock.elapsedRealtimeNanos()) / 1000000L);

However, the same code does not work properly when I read Cell Towers using nearbyCellTowers = mTelephonyManager.getAllCellInfo(); and I have to use this other code:

long timeInMillis = System.currentTimeMillis() + ((gsmRecord.getTimeStamp() -
                    System.nanoTime()) / 1000000L);

If you did not notice the difference, it is in using either SystemClock.elapsedRealtimeNanos() or System.nanoTime().

According to Android documentation getTimeStamp() is:

getTimeStamp(): Approximate time of this cell information in nanos since boot

A similar for WiFi:

timestamp: timestamp in microseconds (since boot) when this result was last seen.

While the descriptions seem identical (time since boot), but the values are totally different. As you can see, WiFi timestamp is comparable to the value of SystemClock.elapsedRealtimeNanos(), while CellInfo timestamp is comparable to System.nanoTime().

I can never say which one would work with which of the two functions unless I debug and look at the results. Am I missing something here? Can someone clarify this for me? What is the main difference between these two functions and why the two timestamps with the same description have different values?

like image 588
Moh Avatar asked Dec 28 '17 19:12

Moh


1 Answers

ScanResult#timestamp and CellInfo#getTimeStamp() is not same. It is pretty clear from the doc.

ScanResult#timestamp

timestamp in microseconds (since boot) when this result was last seen.

I think the word "Since boot" is the one which confuses you. It means the timer will reset when system reboots (and it never means the timer starts when system boots).

CellInfo#getTimeStamp()

Approximate time of this cell information in nanos since boot

Like the previous one, the timer will reset on reboot.


WiFi timestamp is comparable to the value of SystemClock.elapsedRealtimeNanos(), while CellInfo timestamp is comparable to System.nanoTime().

I think you mean "compatible" by "comparable". There is no compatibility issue here. Both SystemClock.elapsedRealtimeNanos() and System.nanoTime()are representation of time as nano seconds.

System.nanoTime()

Returns the current value of the running Java Virtual Machine's high-resolution time source, in nanoseconds. It stops in deep sleep

SystemClock.elapsedRealtimeNanos()

Returns nanoseconds since boot. It will continue to tic even in sleep.




Finally to FreeNickname's question:

From my understanding, simply using System.nanoTime would break older Android versions. And if we want to use different methods on different Android versions, we need to know specifically what versions of Android behave in which way. Or is it vendor-specific?

You can use SystemClock#elapsedRealtime() in all versions of Android. It is introduced in API level 1. Note that unlike elapsedRealtimeNanos(), it returns milliseconds.

like image 120
Bertram Gilfoyle Avatar answered Nov 16 '22 02:11

Bertram Gilfoyle