B4A Library Google Analytics v4 library

Status
Not open for further replies.
Google Analytics V4: https://developers.google.com/analytics/devguides/collection/android/v4/

The instructions were updated to reflect V4 changes. Note that this library will only work with B4A v3.82+.

Setup instructions:
- Download Google Play Services from Android SDK Manager and copy google-play-services.jar to the additional libraries folder.
- Create a Mobile App Analytics account: https://support.google.com/analytics/answer/1042508

The tracker is configured with an XML file. You should create a file with the following text named analytics.xml and put it under Objects\res\xml (create this folder if needed):
<?xml version="1.0" encoding="utf-8" ?>

<resources>
<!--Replace placeholder ID with your tracking ID-->
<string name="ga_trackingId">UA-xxxxx-y</string>

<!--Enable Activity tracking-->
<bool name="ga_autoActivityTracking">true</bool>

<!--Enable automatic exception tracking-->
<bool name="ga_reportUncaughtExceptions">true</bool>

</resources>

Make sure to set this file to be read-only. Otherwise the IDE will delete it during compilation.

You should declare a single AnalyticsTracker in Sub Process_Globals of your main module (or other module). The single tracker should be used from all modules.
B4X:
Sub Process_Globals
   Public tracker As AnalyticsTracker
End Sub

Sub Globals

End Sub

Sub Activity_Create(FirstTime As Boolean)
   If FirstTime Then
     tracker.Initialize
   End If
   tracker.SendScreenView("Main Activity")
End Sub

Other implemented methods: TrackEvent, SendTransaction, SendTiming and SendProduct. Note that you can pass empty strings for optional parameters.
 

Attachments

  • AnalyticsV4.zip
    3.5 KB · Views: 1,031
Last edited:

Dadeda

Member
Licensed User
Longtime User
With a bit of trying and error i got it to work, everything now is working, and it's the objects\res\xml folder :)

Do i need to place tracker.SendScreenView in the activity_resume ?

BTW when i use in my main activity tracker.SendScreenView("test") sometimes in analitycs dashboard it show's up "test" other times it shows up like
com.example.app.main what gives?

Wasn't it suposed to always appear like in the sendview("test") ??
 
Last edited:

korn

Member
Licensed User
Longtime User
Are you using B4A v3.82?

Thanks Erel. Now it works with v3.82 . Sorry i did not read version instruction in first post.

Btw B4A is really awesome. Hope we will have B4I (Basic 4 IOS) soon. :)
 

aaronk

Well-Known Member
Licensed User
Longtime User
Since updating to version 4 I am getting a error:
A referenced library is missing: google-play-services

Any ideas on what I am missing ?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Any ideas on what I am missing ?
You need to download it from Android SDK Manager and copy to the additional libraries folder.

BTW when i use in my main activity tracker.SendScreenView("test") sometimes in analitycs dashboard it show's up "test" other times it shows up like
com.example.app.main what gives?
If ga_autoActivityTracking is set to true in the xml file then you don't need to call SendScreenView (unless you want to track another feature not related to a specific activity).
 

aaronk

Well-Known Member
Licensed User
Longtime User
You need to download it from Android SDK Manager and copy to the additional libraries folder.

Let me know if this is correct..
I copyied the google-play-services.jar file from android\android-sdk\extras\google\google_play_services\libproject\google-play-services_lib\libs and copy it to my B4A lib folder.

I checked my Android SDK Manager and it has the lastest Google Play Services installed (rev 20)

But when I run the code it comes up saying 'Process is running longer then expected. Do you want to canel it?'

The error shows:

Parsing code. 0.17
Compiling code. 0.46
Compiling layouts code. 0.05
Generating R file. 0.06
Compiling generated Java code. 3.68
Convert byte code - optimized dex. Error
UNEXPECTED TOP-LEVEL ERROR:
java.lang.OutOfMemoryError: GC overhead limit exceeded
at com.android.dx.util.IntList.makeImmutable(IntList.java:47)
at com.android.dx.cf.code.ByteCatchList.toTargetList(ByteCatchList.java:176)
at com.android.dx.cf.code.BasicBlocker.visitThrowing(BasicBlocker.java:436)
at com.android.dx.cf.code.BasicBlocker.visitConstant(BasicBlocker.java:210)
at com.android.dx.cf.code.BytecodeArray.parseInstruction(BytecodeArray.java:764)
at com.android.dx.cf.code.BytecodeArray.processWorkSet(BytecodeArray.java:162)
at com.android.dx.cf.code.BasicBlocker.doit(BasicBlocker.java:346)
at com.android.dx.cf.code.BasicBlocker.identifyBlocks(BasicBlocker.java:81)
at com.android.dx.cf.code.Ropper.<init>(Ropper.java:372)
at com.android.dx.cf.code.Ropper.convert(Ropper.java:345)
at com.android.dx.dex.cf.CfTranslator.processMethods(CfTranslator.java:282)
at com.android.dx.dex.cf.CfTranslator.translate0(CfTranslator.java:139)
at com.android.dx.dex.cf.CfTranslator.translate(CfTranslator.java:94)
at com.android.dx.command.dexer.Main.processClass(Main.java:682)
at com.android.dx.command.dexer.Main.processFileBytes(Main.java:634)
at com.android.dx.command.dexer.Main.access$600(Main.java:78)
at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:572)
at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:170)
at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:229)
at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:158)
at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:229)
at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:158)
at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:229)
at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:158)
at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:229)
at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:158)
at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:229)
at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:158)
at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)
at com.android.dx.command.dexer.Main.processOne(Main.java:596)
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:498)
at com.android.dx.command.dexer.Main.runMonoDex(Main.java:264)
Optimized dexer failed. Switching to Standard dexer.

I wasn't getting this error before I copied the google-play-services.jar file.
 

aaronk

Well-Known Member
Licensed User
Longtime User
Thanks Erel.
My MaxRamForDex was set to 512. (I guess this is the default value since I have never changed it before).

Changing it to 1536 fixed the problem I was having.
 

gadgetmonster

Active Member
Licensed User
Longtime User
Hi
I have followed the instructions as follows:

1. Copy the google play services li to the libraries folder (already had it)
2. Created the xml file and added my UA number after creating the account in google
3. Set the xml file to read only
4. Ticked Analytics in my Lib list (version 4)
5. Added

B4X:
Public tracker As AnalyticsTracker

to Sub Process_Globals in my main activity

6. Added

B4X:
If FirstTime Then
    tracker.initialize
End if

tracker.SendScreenView("Main Activity")

to Activity_Create

Now when I run my app I get the error:

Unfortunately xxxxxx has stopped

which is being caused by the initialize line.

Note: my analytics.xml file is in project folder/Objects/res/xml. I have seen mention of a values folder but it wasn't part of Erels instructions.
 
Last edited:

shashkiranr

Active Member
Licensed User
Longtime User
Hi Erel,

I have installed Analytics in my app and complied in release obfuscation mode signed by a private key. I have given the screen name as phone model,phone make and deviceid. when i login into the app and check in real time i always get mypackage.main(com.xxx.main) as the screen name and not phone model,phone make and deviceid which i should get. do you know why it is taking the package name?

Edit : After some time i see my screenname that is phone model,phone make and deviceid along with the default package name mypackage.main(com.xxx.main) so there are two users instead of one.

Regards,
SK
 

TpS

Member
Licensed User
Longtime User
Hello @Erel (and others)
I´we done the exact same setup as @gadgetmonster a few posts up and also receives the "xxxxxxx has stopped error"
My Log says:
B4X:
java.lang.NoClassDefFoundError: com.google.android.gms.analytics.GoogleAnalytics
at anywheresoftware.b4a.objects.AnalyticsTracker.Initialize(AnalyticsTracker.java:32)

Does it make a difference if I use a later Android API Platform? I´m running 18 now
I´m running the latest B4A 3.82, what else might I have missed?
 

TpS

Member
Licensed User
Longtime User
Are you using Java 7 under Tools - Configure Paths?
Yes, "jdk1.7.0_45"

Edit: Downloaded latest JDK (7.0.71) and tried along with Android API 21, and did a complete reinstall of B4A just to make sure that it was all running the latest files, still same error...
 
Last edited:
Status
Not open for further replies.
Top