amplitude / amplitude-android Goto Github PK
View Code? Open in Web Editor NEWNative Android SDK for Amplitude
License: MIT License
Native Android SDK for Amplitude
License: MIT License
After some digging I noticed that the SDK checks "isLimitAdTrackingEnabled" when fetching the advertising ID. This check "could" be removed (or at least provide an override).
Respecting users' selections. Upon reset, a new advertising identifier must not be connected to a previous advertising identifier or data derived from a previous advertising identifier without the explicit consent of the user. Furthermore, you must abide by a user’s “opt out of interest-based advertising” setting. If a user has enabled this setting, you may not use the advertising identifier for creating user profiles for advertising purposes or for targeting users with interest-based advertising. Allowed activities include contextual advertising, frequency capping, conversion tracking, reporting and security and fraud detection.
We're seeing some no such algorithm Exceptions in the wild. Not sure what you can do about that, but it's in your code.
Statistics that I have about devices:
Stack Trace
0 java.lang.AssertionError: java.security.NoSuchAlgorithmException: MessageDigest MD5 implementation not found
1 at org.apache.harmony.xnet.provider.jsse.NativeCrypto.X509_NAME_hash(NativeCrypto.java:188)
2 at org.apache.harmony.xnet.provider.jsse.NativeCrypto.X509_NAME_hash_old(NativeCrypto.java:181)
3 at org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore.hash(TrustedCertificateStore.java:417)
4 at org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore.findCert(TrustedCertificateStore.java:377)
5 at org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore.isTrustAnchor(TrustedCertificateStore.java:326)
6 at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.findTrustAnchorBySubjectAndPublicKey(TrustManagerImpl.java:307)
7 at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.cleanupCertChainAndFindTrustAnchors(TrustManagerImpl.java:237)
8 at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:184)
9 at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:163)
10 at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:573)
11 at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
12 at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:371)
13 at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.getSession(OpenSSLSocketImpl.java:703)
14 at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:92)
15 at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381)
16 at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:165)
17 at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
18 at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
19 at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
20 at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:670)
21 at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:509)
22 at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
23 at com.amplitude.api.Amplitude.makeEventUploadPostRequest(Amplitude.java:411)
24 at com.amplitude.api.Amplitude.access$6(Amplitude.java:369)
25 at com.amplitude.api.Amplitude$5.run(Amplitude.java:359)
26 at android.os.Handler.handleCallback(Handler.java:615)
27 at android.os.Handler.dispatchMessage(Handler.java:92)
28 at android.os.Looper.loop(Looper.java:137)
29 at com.amplitude.api.HTTPThread.run(HTTPThread.java:26)
30 Caused by: java.security.NoSuchAlgorithmException: MessageDigest MD5 implementation not found
31 at org.apache.harmony.security.fortress.Engine.notFound(Engine.java:177)
32 at org.apache.harmony.security.fortress.Engine.getInstance(Engine.java:151)
33 at java.security.MessageDigest.getInstance(MessageDigest.java:91)
34 at org.apache.harmony.xnet.provider.jsse.NativeCrypto.X509_NAME_hash(NativeCrypto.java:185)
35 ... 28 more
36 java.security.NoSuchAlgorithmException: MessageDigest MD5 implementation not found
37 at org.apache.harmony.security.fortress.Engine.notFound(Engine.java:177)
38 at org.apache.harmony.security.fortress.Engine.getInstance(Engine.java:151)
39 at java.security.MessageDigest.getInstance(MessageDigest.java:91)
40 at org.apache.harmony.xnet.provider.jsse.NativeCrypto.X509_NAME_hash(NativeCrypto.java:185)
41 at org.apache.harmony.xnet.provider.jsse.NativeCrypto.X509_NAME_hash_old(NativeCrypto.java:181)
42 at org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore.hash(TrustedCertificateStore.java:417)
43 at org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore.findCert(TrustedCertificateStore.java:377)
44 at org.apache.harmony.xnet.provider.jsse.TrustedCertificateStore.isTrustAnchor(TrustedCertificateStore.java:326)
45 at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.findTrustAnchorBySubjectAndPublicKey(TrustManagerImpl.java:307)
46 at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.cleanupCertChainAndFindTrustAnchors(TrustManagerImpl.java:237)
47 at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:184)
48 at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:163)
49 at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:573)
50 at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
51 at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:371)
52 at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.getSession(OpenSSLSocketImpl.java:703)
53 at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:92)
54 at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381)
55 at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:165)
56 at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
57 at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
58 at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
59 at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:670)
60 at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:509)
61 at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
62 at com.amplitude.api.Amplitude.makeEventUploadPostRequest(Amplitude.java:411)
63 at com.amplitude.api.Amplitude.access$6(Amplitude.java:369)
64 at com.amplitude.api.Amplitude$5.run(Amplitude.java:359)
65 at android.os.Handler.handleCallback(Handler.java:615)
66 at android.os.Handler.dispatchMessage(Handler.java:92)
67 at android.os.Looper.loop(Looper.java:137)
68 at com.amplitude.api.HTTPThread.run(HTTPThread.java:26)
Threads
_________________________________
Thread: FileService$RunLoop
0 java.lang.Object.wait(Native Method)
1 java.lang.Object.wait(Object.java:364)
2 axj.c(FileService.java:516)
3 axj.a(FileService.java:466)
4 axj.run(FileService.java:424)
Thread: Binder_1
0 dalvik.system.NativeStart.run(Native Method)
Thread: GC
0 dalvik.system.NativeStart.run(Native Method)
Thread: Binder_2
0 dalvik.system.NativeStart.run(Native Method)
Thread: java.lang.ProcessManager
0 java.lang.Object.wait(Native Method)
1 java.lang.Object.wait(Object.java:364)
2 java.lang.ProcessManager.waitForMoreChildren(ProcessManager.java:140)
3 java.lang.ProcessManager.watchChildren(ProcessManager.java:105)
4 java.lang.ProcessManager.access$000(ProcessManager.java:40)
5 java.lang.ProcessManager$1.run(ProcessManager.java:58)
Thread: Compiler
0 dalvik.system.NativeStart.run(Native Method)
Thread: Thread-3576
0 android.os.MessageQueue.nativePollOnce(Native Method)
1 android.os.MessageQueue.next(MessageQueue.java:125)
2 android.os.Looper.loop(Looper.java:124)
3 bib.run(AnalyticsMessages.java:187)
Thread: FinalizerWatchdogDaemon
0 java.lang.Object.wait(Native Method)
1 java.lang.Object.wait(Object.java:364)
2 java.lang.Daemons$FinalizerWatchdogDaemon.run(Daemons.java:214)
3 java.lang.Thread.run(Thread.java:856)
Thread: Thread-3571
0 java.lang.Object.wait(Native Method)
1 java.lang.Object.wait(Object.java:364)
2 aka.a(KLog.java:333)
3 aka.run(KLog.java:321)
Thread: FinalizerDaemon
0 java.lang.Object.wait(Native Method)
1 java.lang.Object.wait(Object.java:401)
2 java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:102)
3 java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:73)
4 java.lang.Daemons$FinalizerDaemon.run(Daemons.java:169)
5 java.lang.Thread.run(Thread.java:856)
Thread: Thread-3580
0 android.os.MessageQueue.nativePollOnce(Native Method)
1 android.os.MessageQueue.next(MessageQueue.java:125)
2 android.os.Looper.loop(Looper.java:124)
3 com.amplitude.api.DatabaseThread.run(DatabaseThread.java:26)
Thread: Signal Catcher
0 dalvik.system.NativeStart.run(Native Method)
Thread: main
0 android.text.method.PasswordTransformationMethod$PasswordCharSequence.getChars(PasswordTransformationMethod.java:215)
1 android.text.TextUtils.getChars(TextUtils.java:70)
2 android.text.TextUtils.indexOf(TextUtils.java:103)
3 android.text.StaticLayout.generate(StaticLayout.java:184)
4 android.text.DynamicLayout.reflow(DynamicLayout.java:332)
5 android.text.DynamicLayout.access$000(DynamicLayout.java:41)
6 android.text.DynamicLayout$ChangeWatcher.reflow(DynamicLayout.java:686)
7 android.text.DynamicLayout$ChangeWatcher.onSpanAdded(DynamicLayout.java:705)
8 android.text.SpannableStringBuilder.sendSpanAdded(SpannableStringBuilder.java:979)
9 android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:688)
10 android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:588)
11 android.text.method.PasswordTransformationMethod.onTextChanged(PasswordTransformationMethod.java:108)
12 android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:962)
13 android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:496)
14 android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:435)
15 android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:30)
16 android.text.method.QwertyKeyListener.onKeyDown(QwertyKeyListener.java:222)
17 android.text.method.TextKeyListener.onKeyDown(TextKeyListener.java:136)
18 android.widget.TextView.doKeyDown(TextView.java:5543)
19 android.widget.TextView.onKeyDown(TextView.java:5355)
20 android.view.KeyEvent.dispatch(KeyEvent.java:2705)
21 android.view.View.dispatchKeyEvent(View.java:7221)
22 com.kii.safe.PasswordActivity.handleInput(PasswordActivity.java:936)
23 java.lang.reflect.Method.invokeNative(Native Method)
24 java.lang.reflect.Method.invoke(Method.java:511)
25 android.view.View$1.onClick(View.java:3686)
26 android.view.View.performClick(View.java:4211)
27 android.view.View$PerformClick.run(View.java:17267)
28 android.os.Handler.handleCallback(Handler.java:615)
29 android.os.Handler.dispatchMessage(Handler.java:92)
30 android.os.Looper.loop(Looper.java:137)
31 android.app.ActivityThread.main(ActivityThread.java:4898)
32 java.lang.reflect.Method.invokeNative(Native Method)
33 java.lang.reflect.Method.invoke(Method.java:511)
34 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
35 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
36 dalvik.system.NativeStart.main(Native Method)
Thread: File migration
0 java.util.AbstractList.<init>(AbstractList.java:377)
1 java.util.ArrayList.<init>(ArrayList.java:81)
2 jh.d(TextBuffer.java:663)
3 jh.c(TextBuffer.java:471)
4 hv.write(SegmentedStringWriter.java:67)
5 ij.k(WriterBasedJsonGenerator.java:1908)
6 ij.k(WriterBasedJsonGenerator.java:941)
7 ij.b(WriterBasedJsonGenerator.java:335)
8 yc.a(StringSerializer.java:39)
9 yc.a(StringSerializer.java:21)
10 uf.a(BeanPropertyWriter.java:569)
11 vz.c(BeanSerializerBase.java:597)
12 ug.a(BeanSerializer.java:142)
13 vb.a(IndexedListSerializer.java:100)
14 vb.b(IndexedListSerializer.java:21)
15 vy.a(AsArraySerializerBase.java:186)
16 uf.a(BeanPropertyWriter.java:569)
17 vz.c(BeanSerializerBase.java:597)
18 ug.a(BeanSerializer.java:142)
19 um.a(DefaultSerializerProvider.java:118)
20 ki.b(ObjectMapper.java:2718)
21 ki.a(ObjectMapper.java:2210)
22 alm.a(ManifestManager.java:578)
23 alm.c(ManifestManager.java:141)
24 avq.g(ManifestMigrationUtil.java:426)
25 avq.d(ManifestMigrationUtil.java:189)
26 axl.run(InstallService.java:40)
27 java.lang.Thread.run(Thread.java:856)
Thread: OPTMZ
0 java.lang.VMThread.sleep(Native Method)
1 java.lang.Thread.sleep(Thread.java:1031)
2 java.lang.Thread.sleep(Thread.java:1013)
3 bsa.run(Unknown Source)
4 java.lang.Thread.run(Thread.java:856)
Thread: pool-4-thread-1
0 java.lang.Object.wait(Native Method)
1 java.lang.Thread.parkFor(Thread.java:1231)
2 sun.misc.Unsafe.park(Unsafe.java:323)
3 java.util.concurrent.locks.LockSupport.park(LockSupport.java:157)
4 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2022)
5 java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:413)
6 java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1009)
7 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1069)
8 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
9 java.lang.Thread.run(Thread.java:856)
Thread: ReferenceQueueDaemon
0 java.lang.Object.wait(Native Method)
1 java.lang.Object.wait(Object.java:364)
2 java.lang.Daemons$ReferenceQueueDaemon.run(Daemons.java:129)
3 java.lang.Thread.run(Thread.java:856)
Thread: DispatcherThread
0 android.os.MessageQueue.nativePollOnce(Native Method)
1 android.os.MessageQueue.next(MessageQueue.java:125)
2 android.os.Looper.loop(Looper.java:124)
3 android.os.HandlerThread.run(HandlerThread.java:60)
Hi,
I have a usecase where a user can logout/login under different accounts without closing the app. From what I understand, if I call setUserId
when the user log in to a different account, it will attach all previous events to the new account. Is it possible to call setUserId()
only for future events?
java.lang.NullPointerException
com.amplitude.api.AmplitudeClient.getSharedPreferencesName(AmplitudeClient.java:1054)
com.amplitude.api.AmplitudeClient.getLastEventTime(AmplitudeClient.java:438)
com.amplitude.api.AmplitudeClient.isWithinMinTimeBetweenSessions(AmplitudeClient.java:534)
com.amplitude.api.AmplitudeClient.startNewSessionIfNeeded(AmplitudeClient.java:498)
com.amplitude.api.AmplitudeClient.logEvent(AmplitudeClient.java:333)
com.amplitude.api.AmplitudeClient$2.run(AmplitudeClient.java:313)
android.os.Handler.handleCallback(Handler.java:808)
android.os.Handler.dispatchMessage(Handler.java:103)
android.os.Looper.loop(Looper.java:193)
android.os.HandlerThread.run(HandlerThread.java:61)
Hi Team,
Please check this error.
Fatal Exception: java.lang.OutOfMemoryError
at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:132)
at java.lang.StringBuilder.append(StringBuilder.java:124)
at org.json.JSONStringer.string(JSONStringer.java:344)
at org.json.JSONStringer.key(JSONStringer.java:375)
at org.json.JSONObject.writeTo(JSONObject.java:667)
at org.json.JSONStringer.value(JSONStringer.java:237)
at org.json.JSONArray.writeTo(JSONArray.java:572)
at org.json.JSONArray.toString(JSONArray.java:544)
at com.amplitude.api.AmplitudeClient.updateServer(AmplitudeClient.java:811)
at com.amplitude.api.AmplitudeClient.updateServer(AmplitudeClient.java:789)
at com.amplitude.api.AmplitudeClient$7.run(AmplitudeClient.java:783)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:177)
at android.os.HandlerThread.run(HandlerThread.java:60)
From our crash logs
java.lang.NullPointerException
at com.amplitude.api.DeviceInfo.getMostRecentLocation(Unknown Source)
at com.amplitude.api.Amplitude.logEvent(Unknown Source)
logEvent
logEvent
logEvent
at com.amplitude.api.Amplitude.access$1300(Unknown Source)
at com.amplitude.api.Amplitude$2.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:60)
Hi,
I'm seeing inside the production logs a small amount of crashes.
Looks like FORCE_STOP_PACKAGES permission is missing
Fatal Exception: java.lang.SecurityException: Permission Denial: forceStopPackage() from pid=21114, uid=10091 requires android.permission.FORCE_STOP_PACKAGES
at android.os.Parcel.readException(Parcel.java:1425)
at android.os.Parcel.readException(Parcel.java:1379)
at android.location.ILocationManager$Stub$Proxy.getProviders(ILocationManager.java:851)
at android.location.LocationManager.getProviders(LocationManager.java:321)
at com.amplitude.api.DeviceInfo.getMostRecentLocation(DeviceInfo.java:309)
at com.amplitude.api.DeviceInfo$CachedInfo.getCountryFromLocation(DeviceInfo.java:127)
at com.amplitude.api.DeviceInfo$CachedInfo.getCountry(DeviceInfo.java:110)
at com.amplitude.api.DeviceInfo$CachedInfo.(DeviceInfo.java)
at com.amplitude.api.DeviceInfo$CachedInfo.(DeviceInfo.java)
at com.amplitude.api.DeviceInfo.getCachedInfo(DeviceInfo.java:237)
at com.amplitude.api.DeviceInfo.prefetch(DeviceInfo.java:243)
at com.amplitude.api.AmplitudeClient$1.run(AmplitudeClient.java:163)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:153)
at android.os.HandlerThread.run(HandlerThread.java:60)
Amplitude version 2.7.1
Affected environment: production
Android version: Android 4.x and Android 5.x
Devices:
Thanks for your support.
Hi,
In the README, you recommend initialize SDK in Activity#onCreate()
In the onCreate() of your main activity, initialize the SDK:
Is there any reason we should avoid do this during Application#onCreate?
If users launch our app via push notification, they may not open our "main" activity. Is there any reason you prefer Activity#onCreate over Application#onCreate?
Fatal Exception: android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed.
at android.database.CursorWindow.(CursorWindow.java:108)
at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
at android.database.sqlite.SQLiteCursor.clearOrCreateWindow(SQLiteCursor.java:316)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:142)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:136)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:197)
at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:237)
at com.amplitude.api.DatabaseHelper.getValueFromTable(DatabaseHelper.java:199)
at com.amplitude.api.DatabaseHelper.getLongValue(DatabaseHelper.java:184)
at com.amplitude.api.AmplitudeClient.getNextSequenceNumber(AmplitudeClient.java:431)
at com.amplitude.api.AmplitudeClient.logEvent(AmplitudeClient.java:361)
at com.amplitude.api.AmplitudeClient$2.run(AmplitudeClient.java:317)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.os.HandlerThread.run(HandlerThread.java:61)
It would be nice, that the amplitude android sdk updates to the new okhttp version 3.0.1
Stack Trace:
java.lang.IllegalArgumentException
at android.os.Parcel.readException(Parcel.java:1544)
at android.os.Parcel.readException(Parcel.java:1493)
at android.location.ILocationManager$Stub$Proxy.getLastLocation(ILocationManager.java:734)
at android.location.LocationManager.getLastKnownLocation(LocationManager.java:1232)
at com.amplitude.api.DeviceInfo.getMostRecentLocation(DeviceInfo.java:196)
at com.amplitude.api.DeviceInfo.getCountryFromLocation(DeviceInfo.java:89)
at com.amplitude.api.DeviceInfo.getCountryUncached(DeviceInfo.java:130)
at com.amplitude.api.DeviceInfo.getCountry(DeviceInfo.java:76)
at com.amplitude.api.AmplitudeClient$1.run(AmplitudeClient.java:143)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.os.HandlerThread.run(HandlerThread.java:61)
Amplitude Library Version: 1.7.0
Device: SAMSUNG-SM-G920A (non-rooted)
Android Version: 5.0.2
I don't have access to the device, this is information from our crash reporting tool.
Hi,
I've updated amplitude to version 2.5.1 and I'm getting a lot of crashes. Here's the stacktrace:
Fatal Exception: java.lang.IndexOutOfBoundsException
at java.util.LinkedList.remove(LinkedList.java:660)
at com.amplitude.api.AmplitudeClient.mergeEventsAndIdentifys(AmplitudeClient.java:844)
at com.amplitude.api.AmplitudeClient.updateServer(AmplitudeClient.java:816)
at com.amplitude.api.AmplitudeClient.updateServer(AmplitudeClient.java:789)
at com.amplitude.api.AmplitudeClient$7.run(AmplitudeClient.java:783)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.os.HandlerThread.run(HandlerThread.java:61)
Can you help me please?
Many android apps use maven to manage dependencies. Would be great if you accommodated them.
Using Google Play Services Version 6.1.11 we encounter the following error. Amplitude Version 1.4.1
Stack Trace:
com.amplitude.api.DeviceInfo﹕ Encountered an error connecting to Google Play Services
java.lang.NoSuchMethodException: getAdvertisingIdInfo [class android.content.Context]
at java.lang.Class.getConstructorOrMethod(Class.java:472)
at java.lang.Class.getMethod(Class.java:857)
at com.amplitude.api.DeviceInfo.l(DeviceInfo.java:181)
at com.amplitude.api.Amplitude$1.run(Amplitude.java:121)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.os.HandlerThread.run(HandlerThread.java:61)
We're running into issues with the 1.6.0 Amplitude JAR: java.lang.IllegalArgumentException: already added: Lcom/amplitude/api/Amplitude;
. At first I thought it was an issue in our packaging, but running dx
directly on the JAR fails as well.
Support for dry run to prevent data being sent to Amplitude.
This should be helpful when testing or debugging applications. Google Analytics supports similar configuration. Here
Instead of using JSON objects:
JSONObject eventProperties = new JSONObject();
try {
eventProperties.put("KEY_GOES_HERE", "VALUE_GOES_HERE");
} catch (JSONException exception) {
}
Amplitude.logEvent("Sent Message", eventProperties);
Why not using Java's built in Map ?
Much cleaner IMO and doesn't require exception handling ?
Could be a method overload to keep BC
Following exception appeared on a phone:
android.database.sqlite.SQLiteException: Failed to change locale for db '/data/data/com.alt12.babybumpfree/databases/com.amplitude.api' to 'en_US'.
at android.database.sqlite.SQLiteConnection.setLocaleFromConfiguration(SQLiteConnection.java:386)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:218)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:861)
at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:229)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
at com.amplitude.api.DatabaseHelper.addEvent(DatabaseHelper.java:48)
at com.amplitude.api.Amplitude.logEvent(Amplitude.java:190)
at com.amplitude.api.Amplitude.logEvent(Amplitude.java:185)
at com.amplitude.api.Amplitude.startNewSession(Amplitude.java:320)
at com.amplitude.api.Amplitude.startNewSessionIfNeeded(Amplitude.java:342)
at com.amplitude.api.Amplitude.access$6(Amplitude.java:323)
at com.amplitude.api.Amplitude$4.run(Amplitude.java:367)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:60)
Caused by: android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed (code 11)
at android.database.sqlite.SQLiteConnection.nativeExecuteForString(Native Method)
at android.database.sqlite.SQLiteConnection.executeForString(SQLiteConnection.java:634)
at android.database.sqlite.SQLiteConnection.setLocaleFromConfiguration(SQLiteConnection.java:367)
Since version 1.4 we're getting proguard warnings in amplitude, see stacktrace.
Warning: com.amplitude.api.Amplitude$8$1: can't find referenced method 'void access$1400(boolean)' in program class com.amplitude.api.Amplitude
Warning: there were 1 unresolved references to program class members.
Your input classes appear to be inconsistent.
You may need to recompile the code.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedprogramclassmember)
:proguardBeta FAILED
Our proguard.cfg contains -keep class com.amplitude.api.** {*;}
Android provide smart APIs for non user facing, deferrable background jobs called JobScheduler https://www.youtube.com/watch?v=QdINLG5QrJc.
Uploading analytics is a perfect use case.
It would be great if Amplitude offered APIs to upload analytics synchronously on demand. The API clients could be free to use any smart background APIs they want easily like JobScheduler or similar https://github.com/firebase/firebase-jobdispatcher-android
Hi,
I am using sdk-1.7.0 for my android app and trying to enable foreground tracking for Android API level 14+ but the code is giving compilation error.
here is my code:
Build.gradle :
compile 'com.amplitude:android-sdk:1.7.0'
Java Code:
Amplitude.getInstance().initialize(this, AMPLITUDE_API_KEY);
if (Build.VERSION.SDK_INT > 14) {
Amplitude.getInstance().enableForegroundTracking(this);
}
We've hit this a few times in production, never on our own devices.
I haven't looked too closely, but this seems like a bug in org.json - that index is absurd. The call-site for logEvent
is literally just Amplitude.logEvent(name, obj)
where obj
is a JSONObject
.
Probably nothing to do but catch and log (maybe propagate in some other fashion). My personal opinion is that this shouldn't be thrown in its current form.
java.lang.ArrayIndexOutOfBoundsException: length=3; index=319421760
at java.util.ArrayList.add(ArrayList.java:124)
at java.util.AbstractCollection.toArrayList(AbstractCollection.java:350)
at java.util.AbstractCollection.toArray(AbstractCollection.java:339)
at java.util.ArrayList.(ArrayList.java:97)
at org.json.JSONObject.names(JSONObject.java:677)
at com.amplitude.api.AmplitudeClient.cloneJSONObject(AmplitudeClient.java:885)
at com.amplitude.api.AmplitudeClient.logEventAsync(AmplitudeClient.java:281)
at com.amplitude.api.AmplitudeClient.logEvent(AmplitudeClient.java:250)
at com.amplitude.api.AmplitudeClient.logEvent(AmplitudeClient.java:245)
at com.amplitude.api.Amplitude.logEvent(Amplitude.java:60)
AmplitudeClient#setOptOut()
runs on the main thread.
I call this method directly after initialize()
, so it looks like the database has not been created yet due to a race condition from the backgrounded initialize()
call. This can cause the main thread to be blocked for around 150ms on start. On subsequent calls (once the database has been created), it can still take around 70ms on an emulator.
Any method that has database calls should probably be put into some kind of background task queue. That way they are executed in order, and do not block the main thread.
StrictMode policy violation; ~duration=150 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=65567 violation=2
at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1263)
at libcore.io.BlockGuardOs.stat(BlockGuardOs.java:292)
at java.io.File.isDirectory(File.java:522)
at android.app.ContextImpl.validateFilePath(ContextImpl.java:1931)
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:566)
at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:269)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at com.amplitude.api.DatabaseHelper.insertOrReplaceKeyValueToTable(DatabaseHelper.java:127)
at com.amplitude.api.DatabaseHelper.insertOrReplaceKeyLongValue(DatabaseHelper.java:121)
at com.amplitude.api.AmplitudeClient.setOptOut(AmplitudeClient.java:432)
We're getting a NullPointerException when trying to use PinnedAmplitudeClient with a call to enable foreground tracking:
PinnedAmplitudeClient.getInstance().enableForegroundTracking(this);
I verified that the same crash occurs if you take the tilt maze demo, and switch it to PinnedAmplitudeClient.
stack trace:
04-18 17:51:39.859 E/AndroidRuntime( 4012): FATAL EXCEPTION: logThread
04-18 17:51:39.859 E/AndroidRuntime( 4012): Process: com.example.www, PID: 4012
04-18 17:51:39.859 E/AndroidRuntime( 4012): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Long com.amplitude.api.DatabaseHelper.getLongValue(java.lang.String)' on a null object reference
04-18 17:51:39.859 E/AndroidRuntime( 4012): at com.amplitude.api.AmplitudeClient.getLongvalue(AmplitudeClient.java:453)
04-18 17:51:39.859 E/AndroidRuntime( 4012): at com.amplitude.api.AmplitudeClient.getLastEventTime(AmplitudeClient.java:466)
04-18 17:51:39.859 E/AndroidRuntime( 4012): at com.amplitude.api.AmplitudeClient.isWithinMinTimeBetweenSessions(AmplitudeClient.java:546)
04-18 17:51:39.859 E/AndroidRuntime( 4012): at com.amplitude.api.AmplitudeClient.startNewSessionIfNeeded(AmplitudeClient.java:510)
04-18 17:51:39.859 E/AndroidRuntime( 4012): at com.amplitude.api.AmplitudeClient$4.run(AmplitudeClient.java:599)
04-18 17:51:39.859 E/AndroidRuntime( 4012): at android.os.Handler.handleCallback(Handler.java:739)
04-18 17:51:39.859 E/AndroidRuntime( 4012): at android.os.Handler.dispatchMessage(Handler.java:95)
04-18 17:51:39.859 E/AndroidRuntime( 4012): at android.os.Looper.loop(Looper.java:148)
04-18 17:51:39.859 E/AndroidRuntime( 4012): at android.os.HandlerThread.run(HandlerThread.java:61)
Note that the problem only occurs if enableForegroundTracking()
is used.
As a quick fix, it works with an override of the enableForegroundTracking()
method added to PinnedAmplitudeClient, so that it gives the AmplitudeCallbacks
constructor the PinnedAmplitudeClient instance.
public class PinnedAmplitudeClient extends AmplitudeClient {
public static final String TAG = "com.amplitude.api.PinnedAmplitudeClient";
private static final AmplitudeLog logger = AmplitudeLog.getLogger();
//..................................
//This fixes it:
public AmplitudeClient enableForegroundTracking(Application app) {
if (isUsingForegroundTracking() || !contextAndApiKeySet("enableForegroundTracking()")) {
return instance;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
Log.d("<><>amplitude", "<><><> amplitude Pinned registerActivityLifecycleCallbacks........");
app.registerActivityLifecycleCallbacks(new AmplitudeCallbacks(instance));
}
return instance;
}
}
Android 2.3.3 - 2.3.7
android.database.sqlite.SQLiteException: unable to open database file at android.database.sqlite.SQLiteDatabase.dbopen(Native Method) at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1851) at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:822) at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:856) at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:849) at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:562) at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203) at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:118) at com.amplitude.api.DatabaseHelper.addEvent(DatabaseHelper.java:48) at com.amplitude.api.Amplitude$1.run(Amplitude.java:160) at android.os.Handler.handleCallback(Handler.java:587) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:130) at com.amplitude.api.DatabaseThread.run(DatabaseThread.java:26)
Observed in v1.6.3 on a Samsung Galaxy Grand Prime (SM-G530FZ), Android 4.4.4.
java.lang.NullPointerException
at android.telephony.MultiSimTelephonyManager.isVoiceCapable(MultiSimTelephonyManager.java:441)
at android.telephony.TelephonyManager.getPhoneType(TelephonyManager.java:571)
at com.amplitude.api.DeviceInfo.getCountryFromNetwork(DeviceInfo.java:112)
at com.amplitude.api.DeviceInfo.getCountryUncached(DeviceInfo.java:135)
at com.amplitude.api.DeviceInfo.getCountry(DeviceInfo.java:76)
at com.amplitude.api.AmplitudeClient$1.run(AmplitudeClient.java:137)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.os.HandlerThread.run(HandlerThread.java:61)
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:796)
at java.util.HashMap$EntryIterator.next(HashMap.java:833)
at java.util.HashMap$EntryIterator.next(HashMap.java:831)
at org.json.JSONObject.writeTo(JSONObject.java:666)
at org.json.JSONStringer.value(JSONStringer.java:237)
at org.json.JSONObject.writeTo(JSONObject.java:667)
at org.json.JSONObject.toString(JSONObject.java:636)
at com.amplitude.api.Amplitude.logEvent(Unknown Source)
at com.amplitude.api.Amplitude.logEvent(Unknown Source)
at com.amplitude.api.Amplitude.startNewSession(Unknown Source)
at com.amplitude.api.Amplitude.startNewSessionIfNeeded(Unknown Source)
at com.amplitude.api.Amplitude.access$600(Unknown Source)
at com.amplitude.api.Amplitude$4.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.os.HandlerThread.run(HandlerThread.java:60)
By following the instruction: https://github.com/amplitude/Amplitude-Android, could someone help check?
Exception as below:
05-19 18:20:54.737 28360-28360/com.haiqili.msgads E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.haiqili.msgads, PID: 28360
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/amplitude/api/Amplitude;
Gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.haiqili.msgads"
minSdkVersion 23
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.amplitude:android-sdk:2.7.1'
}
Here is the stacktrace from version 1.6.3
java.lang.NoSuchMethodError: Llibcore/net/UriCodec;.�
at libcore.net.UriCodec.(UriCodec.java:109)
at libcore.net.UriCodec.encode(UriCodec.java:133)
at java.net.URLEncoder.encode(URLEncoder.java:57)
at com.squareup.okhttp.FormEncodingBuilder.add(FormEncodingBuilder.java:40)
at com.amplitude.api.AmplitudeClient.makeEventUploadPostRequest(AmplitudeClient.java:627)
at com.amplitude.api.AmplitudeClient$9.run(AmplitudeClient.java:596)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:60)
I'm running into a null pointer exception if I pass in an empty JSONObject to logEvent
.
Reproducible in a new project with the following lines in the onCreate
of an Activity:
Amplitude.getInstance().initialize(this, "foo");
Amplitude.getInstance().logEvent("bar", new JSONObject());
From the stacktrace (see below) I'm guessing JSONObject#names
returns null if there are no mappings in the JSONObject.
private JSONObject cloneJSONObject(final JSONObject obj) {
JSONArray nameArray = obj.names(); // becomes null
int len = nameArray.length();
04-03 14:38:30.396 1619-1619/com.f2prateek.myapplication E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.f2prateek.myapplication, PID: 1619
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.f2prateek.myapplication/com.f2prateek.myapplication.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int org.json.JSONArray.length()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int org.json.JSONArray.length()' on a null object reference
at com.amplitude.api.AmplitudeClient.cloneJSONObject(AmplitudeClient.java:290)
at com.amplitude.api.AmplitudeClient.logEvent(AmplitudeClient.java:186)
at com.f2prateek.myapplication.MainActivity.onCreate(MainActivity.java:17)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
It would be great if you guys could add a listener for amplitude errors like :
public interface Listener {
void onError(AmplitudeException error);
}
Amplitude sdk users would use it to either logs error via Android Log
and/or report errors to a bug report tool like Crashlytics.
Amplitude support for OkHttp version 3 should include sharing the OkHttp instance as parameter as recommended in OkHttp 3 changelog.
There is no longer a global singleton connection pool. In OkHttp 2.x, all OkHttpClient instances shared a common connection pool by default. In OkHttp 3.x, each new OkHttpClient gets its own private connection pool. Applications should avoid creating many connection pools as doing so prevents connection reuse. Each connection pool holds its own set of connections alive so applications that have many pools also risk exhausting memory!
The best practice in OkHttp 3 is to create a single OkHttpClient instance and share it throughout the application. Requests that needs a customized client should call OkHttpClient.newBuilder() on that shared instance. This allows customization without the drawbacks of separate connection pools.
java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
at android.database.CursorWindow.nativeGetLong(Native Method)
at android.database.CursorWindow.getLong(CursorWindow.java:511)
at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:75)
at com.amplitude.api.DatabaseHelper.getEvents(DatabaseHelper.java:80)
at com.amplitude.api.Amplitude.updateServer(Amplitude.java:455)
at com.amplitude.api.Amplitude.updateServer(Amplitude.java:446)
at com.amplitude.api.Amplitude.logEvent(Amplitude.java:197)
at com.amplitude.api.Amplitude.logEvent(Amplitude.java:185)
at com.amplitude.api.Amplitude.startNewSession(Amplitude.java:320)
at com.amplitude.api.Amplitude.startNewSessionIfNeeded(Amplitude.java:342)
at com.amplitude.api.Amplitude.access$6(Amplitude.java:323)
at com.amplitude.api.Amplitude$4.run(Amplitude.java:367)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:61
I would like to use the setOnce method belongs to Identify class. But I am not able to find it.
Since it seems like issue #19 is not being looked at, the issue still persists even after updating:
Still exists on v1.6.2,
0 android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed.
1 at android.database.CursorWindow.<init>(CursorWindow.java:109)
2 at android.database.CursorWindow.<init>(CursorWindow.java:100)
3 at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
4 at android.database.sqlite.SQLiteCursor.clearOrCreateWindow(SQLiteCursor.java:301)
5 at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:139)
6 at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
7 at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:197)
8 at android.database.AbstractCursor.moveToNext(AbstractCursor.java:245)
9 at com.amplitude.api.DatabaseHelper.getEvents(DatabaseHelper.java:91)
10 at com.amplitude.api.AmplitudeClient.updateServer(AmplitudeClient.java:594)
11 at com.amplitude.api.AmplitudeClient.updateServer(AmplitudeClient.java:582)
12 at com.amplitude.api.AmplitudeClient.access$1400(AmplitudeClient.java:31)
13 at com.amplitude.api.AmplitudeClient$4.run(AmplitudeClient.java:343)
14 at android.os.Handler.handleCallback(Handler.java:733)
15 at android.os.Handler.dispatchMessage(Handler.java:95)
16 at android.os.Looper.loop(Looper.java:136)
17 at android.os.HandlerThread.run(HandlerThread.java:61)
Hi,
I'm having an issue with the library if I define the dependencies using gradle.
I'm unable to import com.amplitude.api (not found) but I can use com.amplitude.security
If I just download the amplitude jar and add it to the Android Studio project, it works like a charm
Hello, this is just a question and not a issue.
Regarding initialization of the context, can this be put in the application object instead of in the MainActivity/every starting activity of the app?
So instead of this:
Amplitude.getInstance().initialize(this,"YOUR_API_KEY_HERE").enableForegroundTracking(getApplication());
It would look more like this:
Amplitude.getInstance().initialize(this,"YOUR_API_KEY_HERE").enableForegroundTracking(this);
I've seen many libraries using this approach for context registering.
Amplitude version 2.7.1:
I have seen the following issue on my LG G3 with Android 5.0, it happened once when my locale was en_ZA, then I changed the locale to en_US and never got the error again but here it is:
05-19 16:23:10.688 2755-2755/com.abtnprojects.ambatana:leakcanary E/SQLiteDatabase: Failed to open database '/data/data/com.packagename/databases/com.amplitude.api'.
android.database.sqlite.SQLiteException: Failed to change locale for db '/data/data/com.packagename/databases/com.amplitude.api' to 'en_ZA'.
at android.database.sqlite.SQLiteConnection.setLocaleFromConfiguration(SQLiteConnection.java:398)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:218)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:907)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:892)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:795)
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:1213)
at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:267)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at com.amplitude.api.DatabaseHelper.insertOrReplaceKeyValueToTable(DatabaseHelper.java:127)
at com.amplitude.api.DatabaseHelper.insertOrReplaceKeyValue(DatabaseHelper.java:116)
at com.amplitude.api.AmplitudeClient.setUserId(AmplitudeClient.java:805)
at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)
Caused by: android.database.sqlite.SQLiteDiskIOException: disk I/O error (code 1802)
at android.database.sqlite.SQLiteConnection.nativeExecute(Native Method)
at android.database.sqlite.SQLiteConnection.execute(SQLiteConnection.java:560)
at android.database.sqlite.SQLiteConnection.setLocaleFromConfiguration(SQLiteConnection.java:371)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:218)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
We started getting this crash since amplitude 2.5.1 and segment integration 1.0.1
Fatal Exception: java.lang.IndexOutOfBoundsException
at java.util.LinkedList.remove(LinkedList.java:660)
at com.amplitude.api.AmplitudeClient.mergeEventsAndIdentifys(AmplitudeClient.java:844)
at com.amplitude.api.AmplitudeClient.updateServer(AmplitudeClient.java:816)
at com.amplitude.api.AmplitudeClient.updateServer(AmplitudeClient.java:789)
at com.amplitude.api.AmplitudeClient$7.run(AmplitudeClient.java:783)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:60)
We're seeing a lot of this crash using v2.5.0. Not sure if its with this SDK or OkHttp. We use OkHttp 2.7.4, which is the latest 2.x release.
Fatal Exception: java.lang.ArrayIndexOutOfBoundsException: length=2048; index=2048
at okio.Buffer.readByte(Buffer.java:280)
at com.squareup.okhttp.HttpUrl.canonicalize(HttpUrl.java:1594)
at com.squareup.okhttp.FormEncodingBuilder.add(FormEncodingBuilder.java:38)
at com.amplitude.api.AmplitudeClient.makeEventUploadPostRequest(AmplitudeClient.java:886)
at com.amplitude.api.AmplitudeClient$8.run(AmplitudeClient.java:816)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:193)
at android.os.HandlerThread.run(HandlerThread.java:61)
Hi,
It seems amp needs okhttp and okio jars included.
Might be nice to show that in the docs.
my 2c,
Jimmy
Android M has removed HTTPClient entirely. Amplitude has switched to OkHttp for making posts, but the client still references Apache - spuriously, from what I can tell.
In any event, the reference means that Amplitude can't be used on M without also including the legacy Apache stuff manually.
As far as I can tell, the fix is one line - replace org.apache.http.conn.HttpHostConnectException
with java.net.ConnectException
in AmplitudeClient#makeEventUploadPostRequest
.
Stack Trace:
java.lang.NoSuchMethodError: Landroid/location/Geocoder;.<init> at com.amplitude.api.DeviceInfo.getGeocoder(DeviceInfo.java:83) at com.amplitude.api.DeviceInfo.getCountryFromLocation(DeviceInfo.java:92) at com.amplitude.api.DeviceInfo.getCountryUncached(DeviceInfo.java:130) at com.amplitude.api.DeviceInfo.getCountry(DeviceInfo.java:76) at com.amplitude.api.AmplitudeClient$1.run(AmplitudeClient.java:143) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.os.HandlerThread.run(HandlerThread.java:61)
Amplitude Library Version: 1.7.0
Device: SPH-L720 (Rooted)
I don't have access to the device, this is information from our crash reporting tool.
In the most recent version (2.0.2) of the SDK both IOException and NullPointerException are caught, but not NoSuchMethodError or a super class of it.
The docs recommend calling Amplitude.getInstance().initialize(...)
in an onCreate
method. However, there are a number or database queries that take place in that call which block the thread they're called on. This has a noticeable impact on application start time.
Here are a couple of the StrictMode reports:
StrictMode policy violation; ~duration=262 ms: android.os.StrictMode$StrictModeDiskWriteViolation: policy=29 violation=1
at android.os.StrictMode$AndroidBlockGuardPolicy.onWriteToDisk(StrictMode.java:1111)
at android.database.sqlite.SQLiteConnection.applyBlockGuardPolicy(SQLiteConnection.java:1247)
at android.database.sqlite.SQLiteConnection.executeForString(SQLiteConnection.java:808)
at android.database.sqlite.SQLiteConnection.setJournalMode(SQLiteConnection.java:490)
at android.database.sqlite.SQLiteConnection.setWalModeFromConfiguration(SQLiteConnection.java:464)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:363)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:228)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:512)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:206)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:178)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:908)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:878)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:699)
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:1585)
at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:283)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
at com.amplitude.api.DatabaseHelper.getValueFromTable(DatabaseHelper.java:207)
at com.amplitude.api.DatabaseHelper.getValue(DatabaseHelper.java:196)
at com.amplitude.api.AmplitudeClient.initialize(AmplitudeClient.java:128)
at com.amplitude.api.AmplitudeClient.initialize(AmplitudeClient.java:101)
StrictMode policy violation; ~duration=268 ms: android.os.StrictMode$StrictModeDiskWriteViolation: policy=29 violation=1
at android.os.StrictMode$AndroidBlockGuardPolicy.onWriteToDisk(StrictMode.java:1111)
at android.database.sqlite.SQLiteConnection.applyBlockGuardPolicy(SQLiteConnection.java:1247)
at android.database.sqlite.SQLiteConnection.executeForString(SQLiteConnection.java:808)
at android.database.sqlite.SQLiteConnection.setJournalMode(SQLiteConnection.java:493)
at android.database.sqlite.SQLiteConnection.setWalModeFromConfiguration(SQLiteConnection.java:464)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:363)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:228)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:512)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:206)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:178)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:908)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:878)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:699)
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:1585)
at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:283)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
at com.amplitude.api.DatabaseHelper.getValueFromTable(DatabaseHelper.java:207)
at com.amplitude.api.DatabaseHelper.getLongValue(DatabaseHelper.java:200)
at com.amplitude.api.AmplitudeClient.upgradeSharedPrefsToDB(AmplitudeClient.java:1239)
at com.amplitude.api.AmplitudeClient.upgradeSharedPrefsToDB(AmplitudeClient.java:1227)
at com.amplitude.api.AmplitudeClient.initialize(AmplitudeClient.java:111)
at com.amplitude.api.AmplitudeClient.initialize(AmplitudeClient.java:101)
Is it possible for the SDK to perform these calls on a background thread?
From our apps crash log
java.lang.NullPointerException
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketFactoryImpl.createSocket(OpenSSLSocketFactoryImpl.java:94)
at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:382)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:165)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
at com.amplitude.api.Amplitude.makeEventUploadPostRequest(Unknown Source)
at com.amplitude.api.Amplitude.access$1200(Unknown Source)
at com.amplitude.api.Amplitude$7.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.os.HandlerThread.run(HandlerThread.java:60)
Hi!
Reviewing my production app logs I've found a weird crash when Amplitude calls to UpdateServer.
It's quite weird, because it only happens to one device model but I'm scared about that the carrier starts to promote that device and becomes popular in the country.
There's no way I can run and debug on this device, it's restricted to Turkey
Fatal Exception: java.lang.NoSuchFieldError: byte.
at com.amplitude.api.AmplitudeClient.updateServer(AmplitudeClient.java:798)
at com.amplitude.api.AmplitudeClient.updateServer(AmplitudeClient.java:778)
at com.amplitude.api.AmplitudeClient$7.run(AmplitudeClient.java:772)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:193)
at android.os.HandlerThread.run(HandlerThread.java:61)
Many thanks for your support
Amplitude version: com.amplitude:android-sdk:1.3
Stack Trace
0 android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed.
1 at android.database.CursorWindow.<init>(CursorWindow.java:108)
2 at android.database.CursorWindow.<init>(CursorWindow.java:100)
3 at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
4 at android.database.sqlite.SQLiteCursor.clearOrCreateWindow(SQLiteCursor.java:301)
5 at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:139)
6 at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
7 at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:197)
8 at android.database.AbstractCursor.moveToNext(AbstractCursor.java:245)
9 at com.amplitude.api.DatabaseHelper.getEvents(Unknown Source)
10 at com.amplitude.api.Amplitude.updateServer(Unknown Source)
11 at com.amplitude.api.Amplitude.updateServer(Unknown Source)
12 at com.amplitude.api.Amplitude.access$100(Unknown Source)
13 at com.amplitude.api.Amplitude$3.run(Unknown Source)
14 at android.os.Handler.handleCallback(Handler.java:733)
15 at android.os.Handler.dispatchMessage(Handler.java:95)
16 at android.os.Looper.loop(Looper.java:157)
17 at android.os.HandlerThread.run(HandlerThread.java:61)
Hi,
We recently noticed that the daily active user has dropped 20% but we also have Flurry daily active users tracking which represent that our daily active user is growing, can you please tell us how do you identify if a user is 'active' in one day? Or point us some way to find the reason?
Thank you.
Hi,
AmplitudeTest is included in the jar. I think it should not be as it references junit and causes proguard to freak out. The class is also missing from the repo.
Thanks,
Tom
It would be awesome if you could release a maven artifact on sonatype!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.