Android SDK - Event Tracking

Analytics Activation

i. Automatic Events

The R1 Connect SDK will automatically capture some generic events in order to get the most meaningful data on how users interact with your application. These events are triggered when the state of the application is changed, and therefore do not require any additional code to work out of the box:

Launch - emitted when the app starts

First Launch - emitted when the app starts for the first time

First Launch After Update - emitted when the app starts for the first time after a version upgrade

Application Opened - emitted when your app is opened after a message is sent.

Session Start - emitted when a new session starts

Session End - emitted when a session ends; includes a Session Length attribute with the session length in seconds

ii. Standard Events

Standard Events cover all the main user flows (login, register, share, purchase...) in a standardized format for optimized reporting on the portal, providing a great foundation for your analytics strategy. They unlock great insights, particularly with respect to user lifetime value.

Note: The last argument in all of the following emitter callbacks, otherInfo, is a HashMap of “key”,”value” pairs or null, which enables you to customize these events as much as you want.

Login

Tracks a user login within the app

R1Emitter.getInstance().emitLogin("userId", "userName", parameters);
// where parameters is a HashMap. Example:
private HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("key","value");

Registration

Records a user registration within the app

R1Emitter.getInstance().emitRegistration("userId", "userName", "country", "city", "state", parameters);
// where parameters is a HashMap. Example:
private HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("key","value");

Facebook connect

Allows access to Facebook services

HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("custom_key","value");
R1Emitter.getInstance().emitFBConnect(socialPermissions, parameters);

where permissions is a List of R1SocialPermissions:

ArrayList<R1SocialPermission> socialPermissions = new ArrayList<R1SocialPermission>();
socialPermissions.add( new R1SocialPermission("permission", true));

Twitter connect

Allows access to Twitter services

HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("custom_key","value");
R1Emitter.getInstance().emitTConnect("userId", "username", socialPermissions, parameters);

where socialPermissions is a list of R1SocialPermissions:

ArrayList<R1SocialPermission> socialPermissions = new ArrayList<R1SocialPermission>();
socialPermissions.add( new R1SocialPermission("permission", true));

User Info

This event enables you to send user profiles to the backend.

UserItem userItem = new UserItem();
userItem.userId = "userId";
userItem.userName = "userName";
userItem.firstName = "firstName";
userItem.lastName = "lastName";
userItem.email = "user@email.net";
userItem.streetAddress = "address";
userItem.phone = "123456";
userItem.zip = "111111";
userItem.city = "City";
userItem.state = "State";

HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("custom_key","value");

R1Emitter.getInstance().emitUserInfo(userItem, parameters);

Upgrade

Tracks an application version upgrade

HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("custom_key","value");

R1Emitter.getInstance().emitUpgrade(parameters);

Trial Upgrade

Tracks an application upgrade from a trial version to a full version

HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("custom_key","value");

R1Emitter.getInstance().emitTrialUpgrade(parameters);

Screen View

Basically, a page view, it provides info about that screen

HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("custom_key","value");

R1Emitter.getInstance().emitAppScreen("title","description","http://www.example.com/path","example.com","path",parameters);

Transaction

EmitItem purchaseItem = new EmitItem();
purchaseItem.storeId = "storeId";
purchaseItem.storeName = "name";
purchaseItem.transactionId = "AE3237DAA";
purchaseItem.cartId = "ABBCCD";
purchaseItem.orderId = "ABCDEF";
purchaseItem.totalSale = 3.2f;
purchaseItem.currency = "EUR";
purchaseItem.shippingCosts = 1.8f;
purchaseItem.transactionTax = 2.5f;

HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("custom_key","value");

R1Emitter.getInstance().emitTransaction(purchaseItem, parameters);

TransactionItem

R1EmitterLineItem lineItem = new R1EmitterLineItem();
lineItem.productId = "productId";
lineItem.productName = "productName";
lineItem.quantity = 5;
lineItem.unitOfMeasure = "parts";
lineItem.msrPrice = 1.3f;
lineItem.pricePaid = 3.4f;
lineItem.currency = "EUR";
lineItem.itemCategory = "items";

HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("custom_key","value");

R1Emitter.getInstance().emitTransactionItem("transactionItemId", lineItem,  parameters);

Create Cart

HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("custom_key","value");

R1Emitter.getInstance().emitCartCreate("cartId", parameters);

Delete Cart

HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("custom_key","value");

R1Emitter.getInstance().emitCartDelete("cartId", parameters);

Add To Cart

R1EmitterLineItem lineItem = new R1EmitterLineItem();
lineItem.productId = "productId";
lineItem.productName = "productName";
lineItem.quantity = 5;
lineItem.unitOfMeasure = "parts";
lineItem.msrPrice = 1.3f;
lineItem.pricePaid = 3.4f;
lineItem.currency = "EUR";
lineItem.itemCategory = "items";

HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("custom_key","value");

R1Emitter.getInstance().emitAddToCart("cartId", lineItem, parameters);

Delete From Cart

R1EmitterLineItem lineItem = new R1EmitterLineItem();
lineItem.productId = "productId";
lineItem.productName = "productName";
lineItem.quantity = 5;
lineItem.unitOfMeasure = "parts";
lineItem.msrPrice = 1.3f;
lineItem.pricePaid = 3.4f;
lineItem.currency = "EUR";
lineItem.itemCategory = "items";

HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("custom_key","value");

R1Emitter.getInstance().emitRemoveFromCart("cartId", lineItem, parameters);

iii. Custom Events

Custom events enable you to create and track specific events that are more closely aligned with your app. If planned and structured correctly, custom events can be strong indicators of user intent and behavior. Some examples include pressing the “like” button, playing a song, changing the screen mode from portrait to landscape, and zooming in or out of an image. These are all actions by the user that could be tracked with events.

To include tracking of custom events for the mobile app, the following callbacks need to be included in the application code:

// Emits a custom event without parameters
R1Emitter.getInstance().emitEvent("Your custom event name");
// Emits a custom event with parameters
private HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("key","value");
R1Emitter.getInstance().emitEvent("Your custom event name", parameters);

iv. In-App Webview Events

By setting up in-app webview events, you can track events that begin inside your native application but are completed in the embedded browser. To do so, you will have to embed some JavaScript in the page that you will want to fire the event, and you need to properly trigger the webview in your application.

JavaScript Setup

To properly fire the event from your webpage, please make the following call:

R1Connect.emitEvent(eventName,eventParameters);

For example, both of the following work. The use of parameters is optional.

R1Connect.emitEvent("Test Event");
R1Connect.emitEvent("Test Event",{"key":"value"});

Additionally, please attach the following r1connect.js file to your webpage:

var R1ConnectBridgePlatforms = {
    UNKNOWN: 0,
    IOS: 1,
    ANDROID: 2
};

window.R1Connect = {
    iosBridgeScheme: "r1connectbridge://",

    platform: R1ConnectBridgePlatforms.UNKNOWN,

    iosURLQueue: [],
    iosInProgress: false,

    buildIOSUrl: function(eventName, parameters) {
        var url = this.iosBridgeScheme + 'emit/?event=' + eventName;

        if (parameters)
            url += '&params='+JSON.stringify(parameters);

        return url;
    },

    sendURLInFrame: function(url) {
        var iframe = document.createElement("IFRAME");
        iframe.setAttribute("src", encodeURI(url));
        document.documentElement.appendChild(iframe);
        iframe.parentNode.removeChild(iframe);

        iframe = null;
    },

    emitEvent: function(eventName, parameters) {
        if (this.platform == R1ConnectBridgePlatforms.UNKNOWN) {
            if (window.R1ConnectJSInterface && window.R1ConnectJSInterface.emit)
                this.platform = R1ConnectBridgePlatforms.ANDROID;
            else
                this.platform = R1ConnectBridgePlatforms.IOS;
        }

        if (this.platform == R1ConnectBridgePlatforms.ANDROID) {
            window.R1ConnectJSInterface.emit(eventName, parameters ? JSON.stringify(parameters) : '');
            return;
        }

        var iosURL = this.buildIOSUrl(eventName, parameters);

        if (this.iosInProgress) {
            this.iosURLQueue.push(iosURL);
            return;
        }

        this.iosInProgress = true;
        this.sendURLInFrame(iosURL);
    },

    iosURLReceived: function() {
        setTimeout(function() {
            window.R1Connect._iosURLReceived();
        }, 0);
    },

    _iosURLReceived: function() {
        if (this.iosURLQueue.length == 0) {
            this.iosInProgress = false;
            return;
        }

        var iosURL = this.iosURLQueue.shift();
        this.sendURLInFrame(iosURL);    
    },
};

Java Setup

To properly handle the events in your application, you need to first inject R1ConnectJSInterface from the R1Connect SDK:

import com.radiumone.emitter.javascript.R1ConnectJSInterface;
webView.addJavascriptInterface( new R1ConnectJSInterface(), "R1ConnectJSInterface");

You then need to enable javascript for the WebView:

WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);

v. Best Practices

Event Naming Convention

One common mistake is to parametrize event names (with user data for example). Event names should be hard-coded values that you use to segement data on a specific category of event.

Example: "ProfileViewing"

Avoid: "Profile Viewing - Lady Gaga's profile"

As you may have thousands of user profiles in your database, it is preferable to keep the event name high level ("ProfileViewing") so you can run interesting anaytics on it. A high level event name will help answer a question like: How many profiles does a user visit every day on average?

Parameter Variance

Another common mistake is to add parameters to the event that have too many possible values. To follow up on the previous example, one may decide to add the number of profile followers as an event parameter:

HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("profileFollowers",profileFollowers);
R1Emitter.getInstance().emitEvent("ProfileViewing", parameters);

Again, the problem here is that each profile may have any number of followers. This will fragment data too much to extract any valuable information.

Instead, a good strategy would be to define relevant buckets that replace the need for high variance parameters. In this case it might be more relevant to separate traffic on the profiles with a lot of followers from traffic on profiles with a few followers. You could define 3 categories:

  • "VERY_INFLUENTIAL" for profiles > 100,000
  • "INFLUENTIAL" for profile > 10,000 and <= 100,000
  • "NON_INFLUENTIAL" for profile <= 10,000

In this case, a proper event could be:

HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("profileFollowersBucket","VERY_INFLUENTIAL");
R1Emitter.getInstance().emitEvent("ProfileViewing", parameters);

This will enable you to create more insightful reports.

vi. Debugging Tool

This tool allows you to verify that the events that you have set up are triggering correctly. You can access the debugging area of the portal to view the JSON events sent by your application.

Setup

To enable the debugging tool, you should create a flat file titled "r1DebugDevices" with a list of advertiser IDs inside of the "assets" folder. There should be one ID per line in your file.

Once you build the app and install it on the same test devices that you added in the DebugDevices file, you should see any action taken in the app appear in the debug section of the portal.

 Next step: Push Notifications

 

Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.
Powered by Zendesk