Giter Site home page Giter Site logo

instacart / truetime-android Goto Github PK

View Code? Open in Web Editor NEW
1.4K 37.0 192.0 719 KB

Android NTP time library. Get the true current time impervious to device clock time changes

Home Page: https://tech.instacart.com/truetime/

License: Apache License 2.0

Java 27.88% Kotlin 72.12%
ntp android clock ntp-server rxjava time truetime sntp mobile

truetime-android's Introduction

TrueTime for Android

TrueTime

⚠️ See work in progress section below. TrueTime is undergoing some changes


Make sure to check out our counterpart too: TrueTime , an NTP library for Swift.

What is TrueTime?

TrueTime is an (S)NTP client for Android. It helps you calculate the date and time "now" impervious to manual changes to device clock time.

Why do I need TrueTime?

In certain applications it becomes important to get the real or "true" date and time. On most devices, if the clock has been changed manually, then a Date() instance gives you a time impacted by local settings.

Users may do this for a variety of reasons, like being in different timezones, trying to be punctual by setting their clocks 5 – 10 minutes early, etc. Your application or service may want a date that is unaffected by these changes and reliable as a source of truth. TrueTime gives you that.

You can read more about the use case in our intro blog post .

How does TrueTime work?

In a conference talk, we explained how the full NTP implementation works. Check the video and slides out for implementation details.

TrueTime has since been migrated to Kotlin & Coroutines and no longer requires the additional Rx dependency. The concept hasn't changed but the above video is still a good explainer on the concept.

How do I use TrueTime?

Installation

We use JitPack to host the library.

Add this to your application's build.gradle file:

repositories {
    maven {
        url "https://jitpack.io"
    }
}

dependencies {
    // ...
    implementation 'com.github.instacart:truetime-android:<release-version>'
}

Usage

In your application class start the TrueTime sync-er like so:

// App.kt
class App : Application() {

    val trueTime = TrueTimeImpl()

    override fun onCreate() {
        super.onCreate()
        trueTime.sync()
    }
}

Once TrueTime gets a fix with an NTP time server, you can simply use:

(application as App).trueTime.now()

Btw don't do ↑, inject TrueTime into your app and then just call trueTime.now()

Installation

Usage

val trueTime = TrueTimeImpl()
trueTime.sync()
trueTime.now()

💥

⚠️ Work in Progress 4.0

With the move to Kotlin & Coroutines TrueTime 4 was a major overhaul. We still haven't ported some of the additional bells & whistles. This section keeps track of those features (that will come in the near future). TrueTime is completely functional without these additional features, so feel free to start using it.

Most of these todos should have corresponding "TODO" comments within the code.

  • Introduce a Cache provider
  • Add an interface CacheProvider so folks can inject in their preferred caching mechanisms
  • Provide a default cache implementation (probably using the non-android version of DataStore)
  • ? Provide example of using this with a Database like Realm
  • Algorithmic improvements

There are some exciting improvements that we have planned and use internally. Will have to upstream these changes (with a cleaner api + implementation)

  • Move android dependency to separate package

There's no reason for TrueTime (with the move to coroutines) to be an "android" library. It can be a pure kotlin lib.

The only remaining dependency is SystemClock (which we should just have a provider for).

  • Utilize all ntp pool addresses from TrueTimeParameters.ntpHostPool

We currently only take the first ntp host pool address from the supplied parameters. In the future, it would be nice to provide multiple ntp "pool" addresses like time.google.com, time.apple.com and utilize all of those to get the "best" value.

  • BootCompletedBroadcastReceiver sample

Everytime a device is rebooted, the Truetime info is invalid. Previous libraries included an actual BroadcastReceiver but this is better handled by the application than the library. For safe measure, I'll include an example of how this can be done in case folks are curious.

License

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

truetime-android's People

Contributors

anjalsaneen avatar dladowitz avatar eranpolo avatar erluxman avatar jawnnypoo avatar kaushikgopal avatar mataanin avatar msanders avatar npace avatar ravidsrk avatar sveltema avatar tonytangandroid avatar vanniktech avatar ztang-zz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

truetime-android's Issues

make TrueTime a Singleton

  • cannot think of any reason why you would need multiple instances of TrueTime.
  • making it a singleton keeps the api more friendly

courtesy @mataanin

Can't resolve

Error:(40, 13) Failed to resolve: com.github.instacart.truetime-android:library:

my compile/target SDK version is 25 - noticed you still use 23

Unchecked exceptions

The SntpClient.requestTime() can throw a RuntimeException() in case the response from the server is not correct and as far as I can tell this exception isn't handled anywhere and it's not documented. So it can crash the whole app just because some input from the server was not as expected. I think there should be a error callback or other mechanism that is transparent for the end developer.

TrueTime caching not working

I'm initializing the library in my application onCreate().
I enabled the cache via: .withSharedPreferences(this) but the method TrueTimeRx.isInitialized() always returns false between application restarts. Also if I try to call TrueTimeRx.now() it throws an exception.

Can anyone confirm if the cache really works? The logs do not state anything going wrong.

Offline Expectations

[Question]
What kind of guarantees can we expect when offline?
Specifically with the use cases of:

  1. user is connected to the internet, user inits truetime, user changes their time, user goes offline, what is the time guarantee for .now()
  2. user is connected to the internet, user inits truetime, user changes their time, user goes offline, app restarts(permission is granted),app is still offline, what is the time guarantee for .now()
  3. both 1 and 2 but user goes offline, then changes their time

initializeRx goes well, but difference with local time is highly variable

Hi everyone and thank you for your code

In my app I get a correct initialization, and then a pretty stable delta with local time when polling every second.
If I restart the application on my Android, the delta is very similar (up to milliseconds).

Fact is, If I restart the application after a day or hours, the delta is very different (can be like seconds different from before!), but still pretty stable if I relaunch the application consecutively.

The application just prints TrueTimeRx.now().getTime()-System.currentTimeMillis();
so I don't think there is some exotic problem there.

Initialization also is done with a wild copypasta:

    TrueTimeRx.build()
            .initializeRx("time.google.com")
            .subscribeOn(Schedulers.io())
            .subscribe(date -> {
                Log.e("TAG", "TrueTime was initialized and we have a time: " + date);
            }, throwable -> {
                throwable.printStackTrace();
            });

Tested on two Android phones (Samsung S6 and Motorola Moto G4).

Any suggestion on what I should investigate?
Thanks in advance

CB

Depends on one or more Android Libraries but is a jar

I have added:

compile("com.github.instacart.truetime-android:library-extension-rx:2.0")

To my gradle file but see following error:

android:prepareDevDebugDependenciesModule 
'com.github.instacart.truetime-android:library-extension-rx:2.0' depends on one or more Android Libraries but is a jar

Failed to resolve

Failed to resolve
compile 'com.github.instacart.truetime-android:library-extension-rx:2.1'

Wrong value for root delay and root dispersion

In SntpClient, the root delay and root dispersion are badly calculated.
In the code, they are evaluated as 32bits long. But in the NTP protocol, they are signed fixed point.

Root delay. 32 bits, signed fixed point.
The total roundtrip delay to the primary reference source, in seconds with the fraction point between bits 15 and 16. Positive and negative values are valid.

Root dispersion. 32 bits, signed fixed point.
The maximum error relative to the primary reference source in seconds with the fraction point between bits 15 and 16. Only positive values greater than zero are valid.

So currently, for example, instead of having a root delay of 0.0312500s, it is calculated as 2048s and then raised an exception (since it is > 100).

To fix this, the signed 'fixed point' integer should be converted to a float value.

  /**
   * Convert a 16.16 fixed-point value to floating point
   * @param val The fixed-point value
   * @return The equivalent floating-point value.
   */
  public static float toFloat(int val) {
    return ((float)val)/65536.0f;
  }

http://stackoverflow.com/questions/8638792/how-to-convert-packed-integer-16-16-fixed-point-to-float

work with truetime in offline mode

I'm using trueTime for getting accurate time and needed to save in shared preferences and use it in offline mode, but when killing the process the value was gone.
TrueTimeRx.build().withSharedPreferences(this)

Invalid response from NTP server. Root delay violation 1828

Seems like a standard use case, but it's not working.

public class MainActivity extends AppCompatActivity {

  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    new AsyncTask<Void, Void, Void>() {
      @Override protected Void doInBackground(Void... params) {
        try {
          TrueTime.build()
              .withLoggingEnabled(true)
              .withSharedPreferences(MainActivity.this)
              .initialize();
        } catch (IOException e) {
          e.printStackTrace();
        }
        return null;
      }
    }.execute();

    setContentView(R.layout.activity_main);

    Button b = (Button) findViewById(R.id.button);
    b.setOnClickListener(new View.OnClickListener() {
      @Override public void onClick(View v) {
        if (TrueTime.isInitialized()) {
          Toast.makeText(MainActivity.this, TrueTime.now().toString(), Toast.LENGTH_SHORT).show();
        }
      }
    });
  }
}

LookAtTheCrashReport.txt

Neither Rx version or Normal version is working

Hi,

Neither Rx version or Normal version is working. Even the Sample is not working

Getting the same error everywhere. Even in Rx version where retry happens 100 times. Also the exception crashes the App.

com.instacart.library.truetime.InvalidNtpServerResponseException: Server response delay too large for comfort 378
                                                                                   at com.instacart.library.truetime.SntpClient.requestTime(SntpClient.java:171)
                                                                                   at com.instacart.library.truetime.TrueTime.requestTime(TrueTime.java:89)
                                                                                   at com.instacart.library.truetime.TrueTime.initialize(TrueTime.java:85)
                                                                                   at com.instacart.library.truetime.TrueTime.initialize(TrueTime.java:49)
                                                                                   at com.instacart.library.sample.SampleActivity$InitTrueTimeAsyncTask.doInBackground(SampleActivity.java:73)
                                                                                   at com.instacart.library.sample.SampleActivity$InitTrueTimeAsyncTask.doInBackground(SampleActivity.java:65)
                                                                                   at android.os.AsyncTask$2.call(AsyncTask.java:295)
                                                                                   at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                                   at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
                                                                                   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                                   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                                   at java.lang.Thread.run(Thread.java:818)

Expected SNTP time from last boot to be cached. couldn't find it.

Hello,
lately I added the TrueTime library in my app, but some clients encounter an issue with it crashing, because of the reason written in the title.

Stacktrace:

Caused by java.lang.RuntimeException: expected SNTP time from last boot to be cached. couldn't find it.
       at com.instacart.library.truetime.TrueTime._getCachedSntpTime(Unknown Source)
       at com.instacart.library.truetime.TrueTime.now(Unknown Source)
       at com.example.data.Handler$1.call(Unknown Source)
       at rx.internal.operators.OnSubscribeFromCallable.call(Unknown Source)
       at rx.internal.operators.OnSubscribeFromCallable.call(Unknown Source)
       at rx.Observable.create(Unknown Source)
       at rx.internal.operators.OperatorSubscribeOn$1.call(Unknown Source)
       at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(Unknown Source)
       at rx.internal.schedulers.ScheduledAction.run(Unknown Source)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:154)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
       at java.lang.Thread.run(Thread.java:818)

Before accessing TrueTime.now() I check if TrueTime is available using TrueTimeRx.isInitialized(), which returns true.

I load TrueTime like follows if it is not initialized yet (TrueTime.isInitialized() returns false):

TrueTimeRx.build()
                .withLoggingEnabled(false)
                .withSharedPreferences(context)
                .initializeRx("time.apple.com")
                .subscribeOn(Schedulers.io())
                .subscribe(new Observer<Date>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                        Timber.v(e, "Could not get TrueTime");
                    }

                    @Override
                    public void onNext(Date date) {
                        Date deviceDate = new Date();
                        long drift = date.getTime() - deviceDate.getTime();
                        Timber.e("TrueTime=%s, local=%s, dif=%s", date, deviceDate, drift);
                    }
                });

According to the documents this should be the correct way to use TrueTime, isn't it?
The issue only happens on 6.0.1 (That's what Crashlytics is telling me at least), and only on Samsung devices.

Am I doing something wrong, or is this an issue with the library? Looking through the source code of the library I cannot find something obvious which can lead to this error, so I can't come up with a way to prevent this from happening. Any help would be appreciated.

Best regards,
Alex

Crash while initializing

Version 2.1

Caused by java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:411)
at com.instacart.library.truetime.TrueTimeRx$6.call(TrueTimeRx.java:191)
at com.instacart.library.truetime.TrueTimeRx$6.call(TrueTimeRx.java:179)
... rx internals ...

Device info

ANR Input dispatching timed out

ANR Input dispatching timed out (Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago. Wait queue length: 14. Wait queue head age: 19030.9ms.)

1 com.instacart.library.truetime.c.a(SntpClient.java:225)
2 com.instacart.library.truetime.e.b(TrueTime.java:41)

we just use TrueTime like this

public class TimeUtils {
        public static long getTrueTimeStamp() {
                if (TrueTime.isInitialized()) {
                    return TrueTime.now().getTime() / 1000;
                } else {
                    return getDeviceTimeStamp();
                }
        }    
} 

"expected SNTP time from last boot to be cached. couldn't find it." with disabled caching

TrueTime 2.2, disabled caching

The code is called in an Application class before true time is ever kicked off.

fun millis() = if (TrueTime.isInitialized()) TrueTime.now().time else System.currentTimeMillis()
fun instant() = Instant.ofEpochMilli(millis())!!
fun now() = OffsetDateTime.ofInstant(instant(), ZoneId.systemDefault())!!

Caused by java.lang.RuntimeException: expected SNTP time from last boot to be cached. couldn't find it.
    at com.instacart.library.truetime.TrueTime._getCachedSntpTime(SourceFile:122)
    at com.instacart.library.truetime.TrueTime.now(SourceFile:28)
    at cz.quickjobs.android.util.Utils.millis(SourceFile:152)
    ...

Crashed on UnknownHostException in Rx chain

TrueTime 2.2.0
Device: Sony F5321
Android: 7.0

Caused by java.net.UnknownHostException: Unable to resolve host "time.google.com": No address associated with hostname
       at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:125)
       at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:74)
       at java.net.InetAddress.getAllByName(InetAddress.java:752)
       at com.instacart.library.truetime.TrueTimeRx$4$2.call(TrueTimeRx.java:113)
       at com.instacart.library.truetime.TrueTimeRx$4$2.call(TrueTimeRx.java:108)
       at rx.internal.operators.OnSubscribeMap$MapSubscriber.onNext(OnSubscribeMap.java:69)
       at rx.internal.util.ScalarSynchronousObservable$ScalarAsyncProducer.call(ScalarSynchronousObservable.java:200)
       at rx.internal.util.ScalarSynchronousObservable$2$1.call(ScalarSynchronousObservable.java:114)
       at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:230)
       at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
       at java.lang.Thread.run(Thread.java:761)
Caused by android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
       at libcore.io.Posix.android_getaddrinfo(Posix.java)
       at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:55)
       at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:106)
       at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:74)
       at java.net.InetAddress.getAllByName(InetAddress.java:752)
       at com.instacart.library.truetime.TrueTimeRx$4$2.call(TrueTimeRx.java:113)
       at com.instacart.library.truetime.TrueTimeRx$4$2.call(TrueTimeRx.java:108)
       at rx.internal.operators.OnSubscribeMap$MapSubscriber.onNext(OnSubscribeMap.java:69)
       at rx.internal.util.ScalarSynchronousObservable$ScalarAsyncProducer.call(ScalarSynchronousObservable.java:200)
       at rx.internal.util.ScalarSynchronousObservable$2$1.call(ScalarSynchronousObservable.java:114)
       at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:230)
       at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
       at java.lang.Thread.run(Thread.java:761)

Question: does Android only use SNTP and no NTP?

Hello

First of all, thank you for your excelent library.

I'm I correct to assume to Android uses SNTP to correct its internal system clock? Thereby, providing a less accurate timestamp opposed to using NTP. Because I've noticed that using SNTP the computed offset between the internal clock and the SNTP-time is highly variable.

Kind regards,
Gilles Callebaut

Fail to initialize Rx library may not be communicated to API consumer

In the Rx version, I understand the errors to get the time from the server are transformed into null Date objects and then emitted.
In case all requests fail immediately (no back-off mechanism), for example when there is a short unavailability of internet connection during initialization, then the observable will complete with 0 items emitted thanks to the filter for nulls.
Imho, this means that initialization will silently fail, the client will get onComplete+unsubscribe without any throwable error and it will not be informed that there was an error initializing the library.

A couple quick patches I can think of are using first() or firstOrDefault() instead of take(1) to make it fail loudly, although without much information about the root cause for the failure.

should we be checking if Truetime is already initialized ?

Question: Should we be checking if TrueTime is initialized already in the initialize calls, or should we only be checking at the time of retrieving now from TrueTime?

have a look at the last comment from #29 by @Shyish for more context.

Currently in the vanilla version of TrueTime: we do the following:

public void initialize() throws IOException {
        initialize(_ntpHost);
        saveTrueTimeInfoToDisk();
    }

protected void initialize(String ntpHost) throws IOException {
        if (isInitialized()) {
            TrueLog.i(TAG, "---- TrueTime already initialized from previous boot/init");
            return;
        }

With the 2.0 rewrite, i removed the check from TrueTimeRx. My thinking was that with the full NTP implementation, trying again could potentially lead to more accurate/ "fresh" results. The vanilla version of TrueTime does not have full NTP implementation, which is why the dilemma of consistency comes to play.

Here are my random questions/thoughts:

  • does clock drift affect the accuracy of TrueTime over time. i.e. after executing a successful TrueTime init call, can i use the same result for a whole year? is there a concept of "expiry" because of the nature of the drift of a hardware device clock?
    • if yes, then we should definitely not check at the time of init as it avoids the unnecessary network call
    • if no, we should definitely check so as to get a more accurate result

Using TrueTime.withSharedPreferences returns wrong time

TT version: 2.2

Just got back a five days old time.

Happened in Genymotion Samsung Galaxy S4 API 17. It also happens on real devices, cannot pinpoint which, since we dismissed the problem at the time.

It is independent of used NTP pool.

Contents of shared prefs:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<long name="com.instacart.library.truetime.cached_sntp_time" value="1491132884332" />
<long name="com.instacart.library.truetime.cached_boot_time" value="1491132738971" />
<long name="com.instacart.library.truetime.cached_device_uptime" value="145361" />
</map>

This may be related to sleep. I put my computer to hibernate, the emulator gets confused when woken up. HTC devices have some sort of soft reboot. Just tossing ideas...

Removing the .withSharedPreferences line fetched time from network and provides correct results.

java.net.SocketException: sendto failed: ENETUNREACH (Network is unreachable)

I'm getting crashes due to this exceptions.

this is the full stacktrace :

Fatal Exception: io.reactivex.exceptions.UndeliverableException: java.net.SocketException: sendto failed: ENETUNREACH (Network is unreachable)
at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:349)
at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.innerError(FlowableFlatMap.java:604)
at io.reactivex.internal.operators.flowable.FlowableFlatMap$InnerSubscriber.onError(FlowableFlatMap.java:665)
at io.reactivex.internal.operators.flowable.FlowableRetryPredicate$RepeatSubscriber.onError(FlowableRetryPredicate.java:81)
at io.reactivex.internal.operators.flowable.FlowableDoOnEach$DoOnEachSubscriber.onError(FlowableDoOnEach.java:110)
at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.onError(FlowableSubscribeOn.java:102)
at io.reactivex.internal.operators.flowable.FlowableCreate$BaseEmitter.onError(FlowableCreate.java:268)
at io.reactivex.internal.operators.flowable.FlowableCreate$BufferAsyncEmitter.drain(FlowableCreate.java:510)
at io.reactivex.internal.operators.flowable.FlowableCreate$BufferAsyncEmitter.onError(FlowableCreate.java:461)
at com.instacart.library.truetime.TrueTimeRx$4$1$2.subscribe(TrueTimeRx.java:201)
at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:72)
at io.reactivex.Flowable.subscribe(Flowable.java:12986)
at io.reactivex.Flowable.subscribe(Flowable.java:12932)
at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:154)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by java.net.SocketException: sendto failed: ENETUNREACH (Network is unreachable)
at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:542)
at libcore.io.IoBridge.sendto(IoBridge.java:511)
at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:184)
at java.net.DatagramSocket.send(DatagramSocket.java:305)
at com.instacart.library.truetime.SntpClient.requestTime(SntpClient.java:114)
at com.instacart.library.truetime.TrueTime.requestTime(TrueTime.java:122)
at com.instacart.library.truetime.TrueTimeRx$4$1$2.subscribe(TrueTimeRx.java:197)
at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:72)
at io.reactivex.Flowable.subscribe(Flowable.java:12986)
at io.reactivex.Flowable.subscribe(Flowable.java:12932)
at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:154)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by android.system.ErrnoException: sendto failed: ENETUNREACH (Network is unreachable)
at libcore.io.Posix.sendtoBytes(Posix.java)
at libcore.io.Posix.sendto(Posix.java:211)
at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:278)
at libcore.io.IoBridge.sendto(IoBridge.java:509)
at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:184)
at java.net.DatagramSocket.send(DatagramSocket.java:305)
at com.instacart.library.truetime.SntpClient.requestTime(SntpClient.java:114)
at com.instacart.library.truetime.TrueTime.requestTime(TrueTime.java:122)
at com.instacart.library.truetime.TrueTimeRx$4$1$2.subscribe(TrueTimeRx.java:197)
at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:72)
at io.reactivex.Flowable.subscribe(Flowable.java:12986)
at io.reactivex.Flowable.subscribe(Flowable.java:12932)
at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:154)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)

why is it happening ?

Causes ANR and SocketTimeoutException on emulators

Simply running the RxTrueTime sample2 on an Android emulator causes java.net.SocketTimeoutException Poll timed out. It's even causing ANR's inside my own project (also on emulators).

Tried this on 2 separate environments running emulators with different Android versions, they all show the same problem.

Everything works fine on my real devices.

Is this expected behavior and can I ignore this or should this actually work?

Logs:


09-19 16:44:26.899 20496-21765/com.instacart.library.truetime D/TrueTimeRx: ---- resolving ntpHost : time.google.com
09-19 16:44:26.901 20496-21768/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 216.239.35.8
09-19 16:44:26.901 20496-21769/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 216.239.35.8
09-19 16:44:26.901 20496-21770/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 216.239.35.8
09-19 16:44:26.902 20496-21771/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 216.239.35.8
09-19 16:44:26.902 20496-21772/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 216.239.35.8
09-19 16:44:26.902 20496-21773/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 2001:4860:4806:8::
09-19 16:44:26.903 20496-21774/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 2001:4860:4806:8::
09-19 16:44:26.903 20496-21775/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 2001:4860:4806:8::
09-19 16:44:26.903 20496-21776/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 2001:4860:4806:8::
09-19 16:44:26.903 20496-21777/com.instacart.library.truetime D/TrueTimeRx: ---- requestTime from: 2001:4860:4806:8::

Logs don't continue after that, it just loops forever and showing the SocketTimeoutException + causing the ANR.

InvalidNtpServerResponseException

Hi i just downloaded this project to see it in action cause i try to run it in my project and i was getting an error but the same error is showing in your project when i click the "GET THE TIME NOW" button:

E/SampleActivity: Exception when trying to get TrueTime
com.instacart.library.truetime.InvalidNtpServerResponseException: Server response delay too large for comfort 142
at com.instacart.library.truetime.SntpClient.requestTime(SntpClient.java:171)
at com.instacart.library.truetime.TrueTime.requestTime(TrueTime.java:89)
at com.instacart.library.truetime.TrueTime.initialize(TrueTime.java:85)
at com.instacart.library.truetime.TrueTime.initialize(TrueTime.java:49)
at com.instacart.library.sample.SampleActivity$InitTrueTimeAsyncTask.doInBackground(SampleActivity.java:75)
at com.instacart.library.sample.SampleActivity$InitTrueTimeAsyncTask.doInBackground(SampleActivity.java:65)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)

UndeliverableException ENETUNREACH (Network is unreachable)

Running on latest version 3.3

compile 'com.github.instacart.truetime-android:library-extension-rx:3.3'
compile "io.reactivex.rxjava2:rxandroid:2.0.1"

We are experiencing crashes on this exception:
Fatal Exception: io.reactivex.exceptions.UndeliverableException java.net.SocketException: sendto failed: ENETUNREACH (Network is unreachable)

Full stack trace:

Fatal Exception: io.reactivex.exceptions.UndeliverableException: java.net.SocketException: sendto failed: ENETUNREACH (Network is unreachable)
       at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:349)
       at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.innerError(FlowableFlatMap.java:604)
       at io.reactivex.internal.operators.flowable.FlowableFlatMap$InnerSubscriber.onError(FlowableFlatMap.java:665)
       at io.reactivex.internal.operators.flowable.FlowableRetryPredicate$RepeatSubscriber.onError(FlowableRetryPredicate.java:81)
       at io.reactivex.internal.operators.flowable.FlowableDoOnEach$DoOnEachSubscriber.onError(FlowableDoOnEach.java:110)
       at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.onError(FlowableSubscribeOn.java:102)
       at io.reactivex.internal.operators.flowable.FlowableCreate$BaseEmitter.onError(FlowableCreate.java:268)
       at io.reactivex.internal.operators.flowable.FlowableCreate$BufferAsyncEmitter.drain(FlowableCreate.java:510)
       at io.reactivex.internal.operators.flowable.FlowableCreate$BufferAsyncEmitter.onError(FlowableCreate.java:461)
       at com.instacart.library.truetime.TrueTimeRx$4$1$2.subscribe(TrueTimeRx.java:201)
       at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:72)
       at io.reactivex.Flowable.subscribe(Flowable.java:12986)
       at io.reactivex.Flowable.subscribe(Flowable.java:12932)
       at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
       at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
       at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
       at java.util.concurrent.FutureTask.run(FutureTask.java:234)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:153)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:267)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
       at java.lang.Thread.run(Thread.java:838)
Caused by java.net.SocketException: sendto failed: ENETUNREACH (Network is unreachable)
       at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:550)
       at libcore.io.IoBridge.sendto(IoBridge.java:519)
       at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:182)
       at java.net.DatagramSocket.send(DatagramSocket.java:280)
       at com.instacart.library.truetime.SntpClient.requestTime(SntpClient.java:114)
       at com.instacart.library.truetime.TrueTime.requestTime(TrueTime.java:122)
       at com.instacart.library.truetime.TrueTimeRx$4$1$2.subscribe(TrueTimeRx.java:197)
       at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:72)
       at io.reactivex.Flowable.subscribe(Flowable.java:12986)
       at io.reactivex.Flowable.subscribe(Flowable.java:12932)
       at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
       at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
       at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
       at java.util.concurrent.FutureTask.run(FutureTask.java:234)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:153)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:267)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
       at java.lang.Thread.run(Thread.java:838)
Caused by libcore.io.ErrnoException: sendto failed: ENETUNREACH (Network is unreachable)
       at libcore.io.Posix.sendtoBytes(Posix.java)
       at libcore.io.Posix.sendto(Posix.java:151)
       at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177)
       at libcore.io.IoBridge.sendto(IoBridge.java:517)
       at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:182)
       at java.net.DatagramSocket.send(DatagramSocket.java:280)
       at com.instacart.library.truetime.SntpClient.requestTime(SntpClient.java:114)
       at com.instacart.library.truetime.TrueTime.requestTime(TrueTime.java:122)
       at com.instacart.library.truetime.TrueTimeRx$4$1$2.subscribe(TrueTimeRx.java:197)
       at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:72)
       at io.reactivex.Flowable.subscribe(Flowable.java:12986)
       at io.reactivex.Flowable.subscribe(Flowable.java:12932)
       at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
       at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
       at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
       at java.util.concurrent.FutureTask.run(FutureTask.java:234)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:153)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:267)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
       at java.lang.Thread.run(Thread.java:838)

Fatal Exception: io.reactivex.exceptions.UndeliverableException: java.io.IOException: Operation not permitted

Recently I started receiving the following crash:

Fatal Exception: io.reactivex.exceptions.UndeliverableException: java.io.IOException: Operation not permitted
       at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:349)
       at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.innerError(FlowableFlatMap.java:604)
       at io.reactivex.internal.operators.flowable.FlowableFlatMap$InnerSubscriber.onError(FlowableFlatMap.java:665)
       at io.reactivex.internal.operators.flowable.FlowableRetryPredicate$RepeatSubscriber.onError(FlowableRetryPredicate.java:81)
       at io.reactivex.internal.operators.flowable.FlowableDoOnEach$DoOnEachSubscriber.onError(FlowableDoOnEach.java:110)
       at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.onError(FlowableSubscribeOn.java:102)
       at io.reactivex.internal.operators.flowable.FlowableCreate$BaseEmitter.onError(FlowableCreate.java:268)
       at io.reactivex.internal.operators.flowable.FlowableCreate$BufferAsyncEmitter.drain(FlowableCreate.java:510)
       at io.reactivex.internal.operators.flowable.FlowableCreate$BufferAsyncEmitter.onError(FlowableCreate.java:461)
       at com.instacart.library.truetime.TrueTimeRx$4$1$2.subscribe(TrueTimeRx.java:201)
       at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:72)
       at io.reactivex.Flowable.subscribe(Flowable.java:12986)
       at io.reactivex.Flowable.subscribe(Flowable.java:12932)
       at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
       at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
       at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
       at java.lang.Thread.run(Thread.java:761)
Caused by java.io.IOException: Operation not permitted
       at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java)
       at java.net.DatagramSocket.send(DatagramSocket.java:691)
       at com.instacart.library.truetime.SntpClient.requestTime(SntpClient.java:114)
       at com.instacart.library.truetime.TrueTime.requestTime(TrueTime.java:122)
       at com.instacart.library.truetime.TrueTimeRx$4$1$2.subscribe(TrueTimeRx.java:197)
       at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:72)
       at io.reactivex.Flowable.subscribe(Flowable.java:12986)
       at io.reactivex.Flowable.subscribe(Flowable.java:12932)
       at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
       at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
       at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
       at java.lang.Thread.run(Thread.java:761)

I've recently updated the initialization to TrueTimeRx. Before this, I haven't received any crashes.
Can you help me solve this?

This is my initialization:

private void initTime() {
    TrueTimeRx.build()
              .initializeRx("time.google.com")
              .subscribeOn(Schedulers.io())
              .subscribe(date -> Timber.v("initTime(): TrueTime was initialized and we have a time: " + date),
                  Throwable::printStackTrace);
  }

Method which I call in onCreate() method of my project Application class.

Exception upon running example code

Hi Guys,
Using
compile 'com.github.instacart.truetime-android:library-extension-rx:2.0'

I seem to be getting the following error when running the below from my application's onCreate

    TrueTimeRx.build()
            .withSharedPreferences(this)
            .withLoggingEnabled(BuildConfig.DEBUG)
            .withRetryCount(3)
            .initializeRx("0.north-america.pool.ntp.org")
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(date -> {
                //Got the time :)
                if(BuildConfig.DEBUG)
                {
                    DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
                    format.setTimeZone(TimeZone.getTimeZone("GMT+02:00"));
                    Toast.makeText(MyApplication.context, "True time retrieved: " + format.format(date), Toast.LENGTH_LONG).show();
                }
            }, throwable -> {
                if(BuildConfig.DEBUG)
                {
                    Toast.makeText(MyApplication.context, "Failed to retrieve true time with error: " + String.valueOf(throwable.getMessage()) , Toast.LENGTH_LONG).show();
                }
                Timber.w(throwable, "Failed to retrieve true NTP time");
            });

rx.exceptions.OnErrorThrowable$OnNextValue: OnError while emitting onNext value: java.util.ArrayList.class

Might this be due to my existing rxjava libs?
compile 'io.reactivex:rxjava:1.2.1'
even if I add
{ exclude group: 'io.reactivex', module: 'rxjava' }
doesn't seem to resolve the issue though

Update android rx example on site

TrueTimeRx.build().initialize(ntpHosts)

Should be

TrueTimeRx.build().initializeRx(ntpHosts) // note the Rx

And perhaps add the ntpHosts string in the example so you don't have to open the sample app.

initializeRx with multiple urls?

I'm using this awesome library for both iOS and Android.

The iOS version has a startWithHostURLs method which accepts an array of NTP urls. (I randomize the order of my NTP server pool given to me by ntp.org since I expect a lot of devices to start near the same time, assuming that makes a difference.)

The Android example shows an initializeRx method which takes a single "NTP pool server host" url with the note "the NTP pool address you provide is resolved into multiple IP addresses." I'm a little confused by that. For example, if I want to use 0.pool.ntp.org, 1.pool.ntp.org, 2.pool.ntp.org, and 3.pool.ntp.org, should I pass one of them (randomly selected) or should I pass "pool.ntp.org" or is there a better/correct option?

New comment:
I used http://ping.eu/nslookup to look up the urls in my pool, and each one returns the same 4 IP addresses but in different orders. That's true for 0.pool.ntp.org - 3.pool.ntp.org as well. Therefore, I see that I can just pass one of the pool urls to initializeRx. Is it possible to "spread the load" equally among all the IP addresses by randomly selecting which url I pass, or does it not matter which one I pass?

Thanks!

TrueTime.isInitialized() should not be static

It will ALWAYS return false due to:

  • SNTP_CLIENT having init flag false by default
  • DISK_CACHE_CLIENT having sharedPrefs == null for the same reason

Also having this method static is very confusing since at the beginning you might think that in order to check wether or not you should call initialize you can do the following:

if (!TrueTimeRx.isInitialized()) 
    TrueTimeRx trueTimeRx = TrueTimeRx.build()
        .withSharedPreferences(this)
        .initialize(...)
        (...)

When in fact you have to do this:

TrueTimeRx trueTimeRx = TrueTimeRx.build().withSharedPreferences(this);

    if (!trueTimeRx.isInitialized()) 
        (...)

Invalid response from NTP server error

 public class PrivacyCall extends MultiDexApplication {
     public void onCreate() {

             TrueTimeRx.build()
                       .withConnectionTimeout(31_428)
                       .withRetryCount(3)
                       .initialize(ntpHosts)
                       .subscribeOn(Schedulers.io())
                       .subscribe();
     }

java.lang.RuntimeException: Invalid response from NTP server. Root delay violation 9153
at com.instacart.library.truetime.extensionrx.TrueTimeRx$2$2.call(TrueTimeRx.java:60)
at com.instacart.library.truetime.extensionrx.TrueTimeRx$2$2.call(TrueTimeRx.java:50)
at rx.internal.operators.OnSubscribeMap$MapSubscriber.onNext(OnSubscribeMap.java:69)
at rx.internal.util.ScalarSynchronousObservable$ScalarAsyncProducer.call(ScalarSynchronousObservable.java:200)
at rx.internal.util.ScalarSynchronousObservable$2$1.call(ScalarSynchronousObservable.java:114)
at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:228)
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.RuntimeException: Invalid response from NTP server. Root delay violation 9153
at com.instacart.library.truetime.SntpClient.requestTime(SntpClient.java:111)
at com.instacart.library.truetime.extensionrx.TrueTimeRx$2$2.call(TrueTimeRx.java:56)
... 12 more
Caused by: rx.exceptions.OnErrorThrowable$OnNextValue: OnError while emitting onNext value: 1.us.pool.ntp.org
at rx.internal.operators.OnSubscribeMap$MapSubscriber.onNext(OnSubscribeMap.java:73)
... 10 more

Cant init Truetime in android. You need to call init() on TrueTime at least once

First of all, I must tell you, there must be version number in description. I cant find it for gradle compile. I ended up with 2.2. Now, I am not able to init Truetime.. It gives me error

"You need to call init() on TrueTime at least once"

I tried apk of this lib from android arsenal.. Its not working. Can you plz help?

Failed to resolve in 3.3

Hi,

I build in SDK target/compile at 26, min is set as 16, and I still have an issue even I added these two repositories :

Error:Failed to resolve: com.github.instacart.truetime-android:library:3.3
Error:Failed to resolve: com.github.instacart.truetime-android:library-extension-rx:3.3

I have to specify that I need to integrate an external SDK (net.crowdconnected.androidcolocator:colocator:2.0.0 from http://maven.crowdconnected.net repository)

Do I have to implement RxJava in my project or something else before ?

Kind regards, and thanks in advance for your help !

Steven

SocketTimeoutException

If connect timeout, throw the exception makes my app dead. 😢

E/TrueTime: TrueTime initialization failed
 java.lang.Throwable: java.net.SocketTimeoutException at com.instacart.library.truetime.TrueTime.initialize(TrueTime.java:62)

Manifest merger failed

When trying to use the TrueTime RX version (via compile 'com.github.instacart.truetime-android:library-extension-rx:2.2'), I get a failure saying "Manifest merger failed". The problem is that the TrueTime library contains an android:label field in its manifest. Perhaps the library can do without specifying it?
Note that the same offending value was removed from the non-RX version (commit fb8c9f0).

(btw, this can be fixed by overriding the android:label via tools:replace, but that's a less elegant solution)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.