Giter VIP home page Giter VIP logo

amplitude-android's People

Contributors

ajhorst avatar alanibrahim avatar alexkorrnd avatar allanca avatar amplitude-sdk-bot avatar bgiori avatar bohan-amplitude avatar curtisliu avatar daisy1754 avatar dantetam avatar djih avatar elevenfive avatar falconandy avatar fkam-tt avatar haoliu-amp avatar hfwang avatar ifrade avatar izaaz avatar joninvski avatar jooohhn avatar justin-fiedler avatar lissf avatar liuyang1520 avatar nlgtuankiet avatar paladin8 avatar qingzhuozhen avatar sskates avatar yuhao900914 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  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

amplitude-android's Issues

isLimitAdTrackingEnabled check not required.

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.

http://stackoverflow.com/a/20358978/966782

java.security.NoSuchAlgorithmException: MessageDigest MD5 implementation not found

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:

crittercism no md5

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)

setUserId() without merging older events with new user id

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?

Nullpointer Exception in initialization

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)

Getting OutofMemoryError in AmplitudeClient in updateServer operation

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)

getMostRecentLocation causing NullPointerException

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)

DeviceInfo.getMostRecentLocation crashes the app

Hi,

I'm seeing inside the production logs a small amount of crashes.
Looks like FORCE_STOP_PACKAGES permission is missing

StackTrace

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)

Environment

Amplitude version 2.7.1
Affected environment: production
Android version: Android 4.x and Android 5.x
Devices:

  • huawei g510_0200
  • samsung_sgh_i527
  • samsung gt_i9060i
  • samsung sm_g530t1
  • vivo 4_8 hd

Thanks for your support.

Initialize SDK in Application class rather than Activity?

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?

ndroid.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed.

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)

java.lang.IllegalArgumentException DeviceInfo

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.

App crashes with IndexOutOfBoundsException

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?

NoSuchMethodException: getAdvertisingIdInfo Google Play Services 6.1.11

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)

Dex failures

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.

https://cloudup.com/c1XWbzqkKd2

Support for dry run to prevent logging

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

cleaner interface with map instead of JSON objects?

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

SQLite exception

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)

Proguard warning in version 1.4

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.** {*;}

enableForegroundTracking method not available

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);
}

ArrayIndexOutOfBoundsException crash from org.json

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() blocks the main thread

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)

NullPointerException when using PinnedAmplitudeClient with enableForegroundTracking()

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;
    }

}

SQLiteException on open DB

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)

NullPointerException in DeviceInfo.getCountry()

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)

ConcurrentModificationException in HashMap

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)

Runtime exception for the first-time amplitude use

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'
}

Amplitude crashing the process

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)

NPE for empty JSONObject

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)

Add listener for amplitude errors instead of logging via Android Log

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.

OkHttp 3 support

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.

IllegalStateException: Couldn't read row 0, col 0 from CursorWindow

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

Still causing app crashes due to failed SQL allocation

Since it seems like issue #19 is not being looked at, the issue still persists even after updating:

Still exists on v1.6.2,

Device types:
image

Android versions:
image

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)

Amplitude artifact in mavencentral is incomplete

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

Amplitude initialize question

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.

SQLite error with locale en_ZA

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) 

Fatal Exception: java.lang.IndexOutOfBoundsException

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)

Event Upload POST out of bounds exception

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)

okhttps jars required

Hi,

It seems amp needs okhttp and okio jars included.
Might be nice to show that in the docs.

my 2c,
Jimmy

Remove references to Apache HTTPClient classes

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.

java.lang.NoSuchMethodError DeviceInfo

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.

`initialize` performs blocking disk operations on the calling thread.

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?

NullPointerException

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)

AmplitudeClient.UpdateServer crash

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

Environment

  • Amplitude version 2.3.0
  • Affected environment: production
  • Android version: Android 4.4.2
  • Device: casper_via_v8 (only)

StackTrace

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

App Crash on SQLite cursor

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)

Daily Active User Data issue

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.

AmplitudeTest included in the jar

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

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.