Getting the Library (Gradle)

Document created by DPM Admin Employee on Jul 14, 2017
Version 1Show Document
  • View in full screen mode

Instrumenting an Android app with Gradle can be done by including the two dependencies to your project’s build.gradle files: one at the project level and one at the application level.

In the project’s build.gradle file, add the following line:

buildscript {     repositories {         // ...     }     dependencies {         classpath 'com.soasta.mpulse:mpulse-android-gradle-plugin:<replace with most recent version>'         // ...     } }

 For versions prior to 2.1, the package was named com.soasta.mpulse:mpulse-plugin instead of com.soasta.mpulse:mpulse-android-gradle-plugin.

At the Android application level, two changes are necessary to make mPulse available in your Android application.

At the top of your application’s build.gradle file, apply the mPulse Gradle plugin:

apply plugin: "com.android.application" apply plugin: "com.soasta.mpulse.android"

 For versions prior to 2.1, the plugin was named com.soasta.mpulse instead of com.soasta.mpulse.android. apply plugin: "com.soasta.mpulse.android" must come after apply plugin: "com.android.application".

Then add the mPulse library to your compilation dependencies:

dependencies {     compile 'com.soasta.mpulse:mpulse-android:<replace with most recent version>'     // ... }

 For versions prior to 2.1, the package was named com.soasta.mpulse:mpulse instead of com.soasta.mpulse:mpulse-android.

For <replace with most recent version>, you can find the most recent version on JCenter or Maven.

Configuration

Initialization

To use the mPulse Native Android API, you must first initialize your Android project with your API Key:

import com.soasta.mpulse.android.MPulse;public static final String MPULSE_API_KEY = "YOUR_API_KEY";// First, initialize with your API Key in the onCreate Method of your ActivityMPulse.sharedInstance().initializeWithAPIKey(MPULSE_API_KEY, getApplicationContext());// Later, you can interact with MPulse by getting the shared instanceMPulse mpulse = MPulse.sharedInstance();

After you’ve called initializeWithAPIKey(), you can access the shared instance by calling MPulse.sharedInstance().

In most cases, it makes sense to do this in your main Activity’s onCreate() method.

Note: Do not call initializeWithAPIKey() in Application.onCreate(), as the mPulse Native Android library requires an active Activity to initialize.

ProGuard

If you are using ProGuard with minifyEnabled, you will need to add the following to your proguard-rules.pro file:

-keep class com.soasta.** { *; } -keepattributes Signature

Permissions

In order to send beacons the following Android permissions are required:

  • android.permission.INTERNET

  • android.permission.ACCESS_NETWORK_STATE

Capturing location data is optional and can be activated by adding one of the following permissions:

  • android.permission.ACCESS_COARSE_LOCATION

Or

  • android.permission.ACCESS_FINE_LOCATION

Example AndroidManifest.xml lines:

<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Automatic Network Request Instrumentation

Once included in the project, mPulse will automatically instrument all network requests.

Network requests will be instrumented as long as they are sent from one of the following classes (or a library that uses one of these classes):

  • java.net.URLConnection
  • com.squareup.okhttp.OkHttpClient version 1.x
  • okhttp3.OkHttpClient version 3.x (after version 2.2.0)

Excluding libraries from instrumentation

 This is a new feature available with mPulse Native for Android Gradle Plugin version 2.2.2

Should you wish to not instrument a library that is part of your project you can exclude it by using the following configuration closure in your application’s build.gradle file:

mpulseAndroid {   exclude ~/.*do-not-instrument.*/ }

Notice that the exclude function inside the mpulseAndroid closure accepts Groovy Patterns using the Pattern operator. With this mechanism you can exclude as many JARs as you wish:

mpulseAndroid {   exclude ~/.*something\.aar$/   exclude ~/.*something\.jar$/ }

If you wish to exclude the contents of a longer directory path that contains libraries you are using in your project be caucious of using platform specific path seperators:

mpulseAndroid {   exclude ~".*${File.separator}special-libs${File.separator}.*" }

Send a Custom Timer

The mPulse Android Native API can be used to send a Custom Timer.

You can track the time it took for an action to occur, such as an image upload or an attachment file download, using Custom Timers.

At the start of your action, call startTimer() by giving it a timerName. startTimer() will return a unique Timer ID (String) and will keep track of the start time:

String timerID = MPulse.sharedInstance().startTimer("MyTimer");// -> "MyTimer-d4d67062-7064-42b5-85ed-4e69d8824ef9"

At the end of your action, call stopTimer() by passing in the Timer ID. mPulse stops the timer and sends a beacon to the server:

MPulse.sharedInstance().stopTimer(timerID);

You may also directly specify a timer name and value using sendTimer():

// value is in millisecondsMPulse.sharedInstance().sendTimer("MyTimer", 4);

 The value passed to sendTimer() in Android is a long (in milliseconds) while it is a NSTimeInterval (in seconds.milliseconds) in iOS.

Send a Custom Metric

You may increment a Custom Metric by using sendMetric():

MPulse.sharedInstance().sendMetric("MyMetric", new Integer(23));

Set View Groups

You may get, set, and reset the View Group. Once set, the View Group will be associated with every subsequent beacon.

Set a View Group using setViewGroup():

MPulse.sharedInstance().setViewGroup("MyViewGroup");

Reset the View Group using resetViewGroup():

MPulse.sharedInstance().resetViewGroup();

Get the current View Group using getViewGroup():

String viewGroup = MPulse.sharedInstance().getViewGroup();

Set Custom Dimensions

You may get, set, and reset Custom Dimensions. Once set, the Custom Dimension will be associated with every subsequent beacon.

Set or reset a Custom Dimension using setDimension():

MPulse.sharedInstance().setDimension("MyDimension", "new value");

Reset the Custom Dimension using resetDimension():

MPulse.sharedInstance().resetDimension("MyDimension");

Troubleshooting

Build Failure (Gradle)

If you see build failures similar to these:

Error:Uncaught translation error: com.android.dx.cf.code.SimException: local variable type mismatch: attempt to set or access a value of type java.lang.Object using a local variable of type int. This is symptomatic of .class transformation tools that ignore local variable information.

or

com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException

Then your build most likely failed because the mPulse Android Gradle Plugin failed to instrument a JAR in your application. This often happens when one of your JARs is obfuscated.

Finding JAR files that failed to instrument

To find out which of your JARs failed to instrument, run Gradle from the command line with the flags --debug, --info and --full-stacktrace. With these flags set, you will be able to see which of your JARs our plugin attempted to instrument before failing the build:

MPulseAndroidTransform: Weaving file from /some/path/to/a/file.jar MPulseAndroidTransform: woven class com.example.app.a.b.c ...

Should you see this followed by an exception this may indicate that the file.jar is failing the build. You can exclude it from instrumentation and thus from throwing an error like this in your build.gradle file:

android { /* ... */ }  /* add this to your code to exclude file.jar from being instrumented */ mpulseAndroid {   exclude ~/.*file.*/; }  dependencies { /* ... */ }

Notice that the mpulseAndroid closure is invoked at the top-level of your build.gradle file.

Runtime Exceptions after Upgrade 2.x to 2.2.x

Once you have upgraded your version of mPulse native for Android and have run a new successful build you may run into the following exception:

Process: com.example.App, PID: 1234   java.lang.NoClassDefFoundError: Failed resolution of: Lcom/soasta/mpulse/android/MPLog;   /* Long stacktrace pointing to code in third party instrumented library such as Volley */

If so, you may have an issue with a cached compiled version of your application where a previously instrumented version of a third party library is still available. In this specific case, com.soasta.mpulse.android.MPLog was moved to com.soasta.mpulse.core.MPLog.

To prevent this error, you will need to run the following:

In your project directory: $> gradle clean ... $> rm -rf build/

This will remove both build artifacts hidden in the .gradle/ and build/ directories of your project.

The same should be done in any subprojects and folders that also contain a build/ or .gradle/ directory, specific to your Android application.

No Beacons Being Sent

If you are not seeing beacons in the mPulse dashboards, please ensure the app has been configured correctly:

  • If the application is being built with Ant, ensure you have configured AddMPulse
  • If the application is being built with Gradle, ensure Gradle is configured properly:
    • classpath 'com.soasta.mpulse:...' was added to the project’s build.gradle
    • apply plugin: "com.soasta.mpulse.android" was added to the application’s build.gradle after apply plugin: "com.android.application" For versions prior to 2.1, the plugin was named com.soasta.mpulse instead of com.soasta.mpulse.android.
    • compile 'com.soasta.mpulse:...' was added to the application’s build.gradle
  • Ensure you are using the correct mPulse API Key in initializeWithAPIKey
  • Ensure initializeWithAPIKey is being called after an Activity has been created (and not in Application.onCreate())
  • If you are using ProGuard, ensure sure you’ve updated proguard-rules.pro per the instructions
    • If you see beacons for Debug builds, but not for Release builds, this is a common cause
  • Ensure you’ve updated your AndroidManifest.xml with the correct permissions
  • Ensure you don’t see a Unable to refresh Config warning in the logs (see below)
  • Ensure you don’t see a Activity context not available warning in the logs (see below)
  • Ensure you see the following lines in the ADB log after the application has started: E/MPulse.MPulseInternal: [main] mPulse Mobile build: n.n.n E/MPulse.MPulseInternal: [main] mPulse initialized. E/MPulse.MPSession: [pool-n-thread-n] mPulse session has started.
  • If you are trying to send a Custom Timer or Custom Metric, ensure they have already been defined in the mPulse app configuration
  • Using a system proxy such as Fiddler or Charles, validate that:

Unable to Refresh Config (log message)

The following message in your ADB log indicates that config.json could not be fetched:

W/MPulse.MPulseInternal: [pool-1-thread-1] Unable to refresh Config.     java.util.concurrent.TimeoutException     at java.util.concurrent.FutureTask.get     at android.os.AsyncTask.get     at com.soasta.mpulse.android.config.MPConfig.initWithURL     at com.soasta.mpulse.android.config.MPConfig.refresh     at com.soasta.mpulse.android.MPulseInternal$1.run ...

If you see this message, it means that mPulse was unable to initialize because it could not fetch the mPulse app configuration. No beacons will be sent.

Please ensure your app can connect to c.go-mpulse.net and that it is not blocked by the application or a firewall.

Activity Context Not Available (log message)

The following message in your ADB log indicates the application may not have been configured properly:

W/MPulse.MPDemographics: Activity context not available...

If you see this message, it means that build.gradle was not configured properly. No beacons will be sent.

Please ensure the apply plugin line is in your project’s build.gradle file:

apply plugin: "com.soasta.mpulse.android"

 For versions prior to 2.1, the plugin was named `com.soasta.mpulse` instead of `com.soasta.mpulse.android`.

Debugging Output

To add debugging output, add the following line to the import section:

import com.soasta.mpulse.core.MPLog;

Then add the line below to activate debugging:

MPLog.setDebug(true);

Compilation Errors

If the application is not compiling, please check the following:

  • If the application is being built with Gradle, ensure Gradle is configured properly:
    • classpath 'com.soasta.mpulse:...' was added to the project’s build.gradle
    • apply plugin: "com.soasta.mpulse.android" was added to the application’s build.gradle after apply plugin: "com.android.application" For versions prior to 2.1, the plugin was named com.soasta.mpulse instead of com.soasta.mpulse.android.
    • compile 'com.soasta.mpulse:...' was added to the application’s build.gradle

Attachments

    Outcomes