It is a fact that both uptime -s and Kotlin:
object X {
private val startTime = Clock.System.now()
private val androidBootTime = startTime -
SystemClock.elapsedRealtime().toDuration(DurationUnit.MILLISECONDS)
with X referenced by an Application subclass, returns an accuracy that is around ±10 seconds, ie. different invocations produce different boot times for the same boot session
Is there a Kotlin code-sample producing μs-accuracy boot time?
What is the highest attainable accuracy of Android boot time?
It is also a fact that determining the start time of your app can only be done by a static timestamp, all other intelligent means are defeated by Android caching and intentional slowness
Android boot uniqifiers
October 29 2024 update:
there is boot counter Android 7+ api level 24+
int boot_count = Settings.Global.getInt(getContext().getContentResolver(),
Settings.Global.BOOT_COUNT);
there is boot session uuid:
cat /proc/sys/kernel/random/boot_id
c4dfb88f-2a9a-49cf-a649-291b4969db88
there is btime, unix epoch second precision:
cat /proc/stat | grep btime
btime 1729814103
When a poor backup-battery Android boots up, time may be incorrect
apparently uptime -s reads
cat /proc/uptime
408824.96 624814.45
so this in between two clock reads can obtain some kind of precision, like take average, round to nearest second or such if time difference is less than ms or so
The way forward is boot receiver and periodic uniqifier reads, the first estimated boot time value considered authoritative. empiric evidence to select method
UI issues
Android UI may restart, too. I have found two situations in logcat:
- WATCHDOG kills a deadlocked UI thread
- DeadSystemException
If an app has a background service with restart that should never exit, this may be detected
it might be helpful to stream logcat to sd card which is 150 MiB 1M lines per day
Conclusions October 29 22024
I will use a boot uniqifier and the first calculated boot time
That’s all Android can do.
.
boot counter works until reset 1...
boot UUID works
/proc/uptime is as bad as Android SystemClock.elapsedRealtime
/proc/stat is not readable without root permission but btime is accurate to the second (in a good battery real Android)
241105 for 2024 Android 12:
- boot with bad back-up battery may start with inaccurate time
uptime -sand /proc/stat btime are obviously bad- after correcting system time via NTP from the Internet, both values change
- therefore, any reference to Android boot time will suffer from an inaccuracy of ±10 seconds due to Android idiosyncrasies even when system time is highly accurate. The produced time may be different for different attempts
- however, the boot uniquifiers work to distinguish boot events
- the boot time estimate should not be acquired until system time is known to be accurate. For example, verify Android time accuracy to be better than 2 minutes by connecting to an https site or consulting NTP PTP NITZ GPS
Android time detection via NTP NITZ as of 2024 Android 12:
- is only attempted every 18 hours
- only corrects if time deviation more than 5 seconds
- if NTP cannot be read within 3 minutes, Android waits another 18 hours
- time update can be attempted within Android limitations by Settings — System — Date & time — Set time automatically to Off to On
- if a recent NTP request somehow failed, it’s wait 18 hours or set time manually per the dumb Googlers’ design
- it is not possible to force a time update other than Settings — System — Date & time
- need to be signed by Google or system app
- Note that if time is off 2 minutes or more, certificates will not work as in VPN may fail. Android connectivity check may then fail, so Android cannot connect to the Internet at all
- Android with bad backup battery may start with time set to 1969
- Then, the build-time of the operating system is used which may be 2022 or so
- It is not until a timestamp can be obtained from a mobile system or the Internet that time is corrected
What is really dumb by them Googlers is the 5 seconds allowance. In 2024. Should be 1 ms. Costs nothing
- Impact is a user-perceivable time error of ±5 seconds that is completely unnecessary. This is why Android does not show seconds: It’s a Pentagon-papers cover-up
- Impact is that any timestamp reported by Android is ±10 seconds
- If time error is allowed greater than 100 ms, users will notice, Google?
To claim that this is shitty and dumb and idiotic is an understatement. It’s Google trying to make Android safe without a plan
The way to set Android time December 1 2024
Android receives time from a host computer connected via adb
- Time accuracy can be checked via Internet-ntp or a gps-fix
- Plug in the device to adb, Settings — System — Date & time — Set time automatically: Off—On
- If a failed ntp attempt was not made within preceding 18 hours and other conditions above, time will update to that of the host. It appears Android adb time has less restrictions compared to ntp time. Maybe time is always updated?
- logcat will show:
2024年12月01日 06:55:37.715566 1000 1900 1945 D
AlarmManagerService: Setting time of day to sec=1733064917
2024年12月01日 06:55:17.423629 1000 1900 1900 D
ConditionProviders.SCP: onReceive android.intent.action.TIME_SET
2024年12月01日 06:55:17.423826 1000 1900 1900 D
ConditionProviders.SCP: evaluateSubscriptionLocked
cal=ScheduleCalendar[mDays={1, 2, 3, 4, 5, 6, 7},
mSchedule=ScheduleInfo{days=[1, 2, 3, 4, 5, 6, 7],
startHour=22, startMinute=0, endHour=7, endMinute=0,
exitAtAlarm=true,
nextAlarm=Wed Dec 31 16:00:00 PST 1969 (0)}],
now=Sun Dec 01 06:55:17 PST 2024 (1733064917423),
nextUserAlarmTime=Wed Dec 31 16:00:00 PST 1969 (0)
2024年12月01日 06:55:17.433269 1000 1900 1957 I
UsageStatsService: User[0] Time changed in by -20 seconds
2024年12月01日 06:55:17.548695 1000 1900 1957 I
UsageStatsDatabase: Time changed by -20s313ms. files deleted: 0 files moved: 19
2024年12月01日 06:55:18.072561 10197 26701 26701 D
WM-RescheduleReceiver: Received intent Intent {
act=android.intent.action.TIME_SET flg=0x25200010
cmp=com.google.android.apps.messaging/
androidx.work.impl.background.systemalarm.RescheduleReceiver }
2024年12月01日 06:55:18.090800 1000 1900 1957 I
UsageStatsService: Time changed in by -20 seconds
2024年12月01日 06:55:19.499607 10144 3084 3206 W
UsageSyncManager: <DWB> Last (TimeDelta{
wallTime=2024年11月30日T19:32:34.447Z,
elapsedSinceBoot=PT52.836S},
boot count 30) and current (TimeDelta{
wallTime=2024年12月01日T14:55:19.482Z,
elapsedSinceBoot=PT19H23M58.184S},
boot count 30) deltas are different.
Increase event shift by PT-20.313S.
To check device time, on macOS host do:
date "+%F %T%z" && adb shell date -In
2024年12月01日 07:38:26-0800
2024年12月01日T07:38:26,172221743-08:00
or, since macOS BSD cannot do nanoseconds:
python3 -c 'import datetime; print(datetime.datetime.now().astimezone())';
adb shell date -In
2024年12月01日 08:05:00.108809-08:00
2024年12月01日T08:05:00,252027835-08:00
1 Answer 1
.
Boot timestamps from android has accuracy of ±10 s
.
Kotlin and app processing introduces an additional 1.001 ms error, but cannot improve on Android’s built-in ±10 s error
By coaxing Android to correct its time, a boot timestamp error of ±200 ms is attainable
If boot timestamp is read via adb or other low-jitter and latency connection, both boot timestamp and Android time error can be read providing and accuracy of possibly ±10 ms
.
- Boot time depends on the time error of Android’s device clock
- Every time Android time is adjusted, reported boot-time changes
- Dumb Google allows Android time to vary ±5 s meaning any timestamp from Android is ±10 s
- Time can only be adjusted by Android system app or app signed by Google
- Android built-in time correction is only to within ±200 ms
.
The way to adjust time on Android when off by too much:
- with Internet available Settings — System — Date & time — Set time automatically: Off
- set Android time to error larger than 5 s but less than 2 minutes
- Settings — System — Date & time — Set time automatically: On
- Android should adjust time to within 200 ms
- if this fails, wait 18 hours and try again
.
Android time error can be verified via
- adb: compare
date -In(capital-i) to host time - app: comparing gps fix to Android time
- app: comparing ntp or other Internet time source to Android time
.
Check for Android time-correction events using adb:
adb logcat -d --format=printable,uid,usec,year | grep android.intent.action.TIME_SET
2025年01月25日 09:23:00.036705 1000 1802 1802 D ConditionProviders.SCP: onReceive android.intent.action.TIME_SET
uptime -srepeatedly in Termux. I want to track unexpected Android reboots to make sure my Androids are stable. This is easier if the boot time is consistent. Maybe there is a boot uuid number like on Linux?