Android (x)
Prerequisites
Things to keep handy before starting your integration with Apxor
Please have the following handy before beginning the integration:
Application identifier generated on the Apxor dashboard for your app (Read more on how to fetch the application identifier from the Apxor dashboard)
App Bundle Id: Every Android app has a unique application ID that looks like
com.example.myapp
. This ID uniquely identifies the app on the device and also on the Google Play Store.
(Know more about bundle IDs here)
The list of events to set up triggers and track goals, user properties that allow to personalize messages and to target better. (Read more on how you can setup here)
Firebase Cloud Messaging (FCM) Server Key: To track uninstalls, Apxor sends silent push notifications to measure your campaign outcomes. (Read more on how to fetch Firebase credentials that are used to set uninstall tracking during integration here)
Understanding dependencies to add to your project
apxor-android-sdk-core
Core Plugin is used to track events for to measure their results and consists of essential information that controls other plugins.
How many of my users have clicked on the cart icon after showing them a nudge Sample Event : 'ViewCart'
apxor-android-sdk-qe
plugin is used to setup behavioural triggers for the campaigns which helps to setup campaign rules.
Show a campaign to users who land on the home screen and add an item to the cart.
apxor-android-sdk-rtm
plugin is used for the show experiences created from the design library using the Apxor dashboard.
Show a tooltip on the cart icon with messaging "Tap here to view items"
com.apxor.android:surveys
plugin is used to show surveys created using the Apxor dashboard.
An NPS survey that would ask the user to rate the app experience on a scale of 1-10.
com.apxor.android:wysiwyg
plugin is used to facilitate creation of campaigns by mirroring your mobile screen to identify the right UI element to show the campaign.
Casting your mobile screen to the dashboard and selecting the hamburger icon
Integration and Initialization
Step 1: Add Apxor Repository
Add Maven URL in project level build.gradle
file
Path: <project>/build.gradle
:
allprojects {
repositories {
// ...
maven {
url "https://repo.apxor.com/artifactory/list/libs-release-android/"
}
// ...
}
}

Step 2: Add dependencies
Add plugin dependencies to your application build.gradle
file
Path: <project>/<app-module>/build.gradle
:
Check the latest release notes here.
2.1 ApxorSDK dependencies (mandatory)
dependencies {
//...
// Event tracking and a must-have dependency for other plugins
implementation 'com.apxor.androidx:apxor-android-sdk-core:3.2.2@aar'
// Add these for Realtime Actions and Surveys
implementation 'com.apxor.androidx:apxor-android-sdk-qe:1.8.6@aar'
implementation 'com.apxor.androidx:apxor-android-sdk-rtm:2.6.6@aar'
implementation 'com.apxor.androidx:surveys:2.2.7@aar'
// Helper plugin to create walkthroughs
implementation 'com.apxor.androidx:wysiwyg:1.6.3@aar'
// Add the below two dependencies to establish an SSE connection for WYSIWYG
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
implementation 'com.launchdarkly:okhttp-eventsource:2.5.0'
//...
}
2.2 Add exoplayer in your app (optional)
2.3 Enable uninstall tracking for your users (optional)
2.4 Install Referrer Dependency (optional)
Step 3: Add the following in proguard-rules.pro
Configure the below rules in your proguard-rules.pro
file
Path: <project>/<app-module>/proguard-rules.pro
:
-keep class com.apxor.** { *; }
-dontwarn com.apxor.**
Step 4: Disable Dexing Artifact Transformation
Add the following to gradle.properties
file
Path: <project>/<app-module>/gradle.properties
:
android.enableDexingArtifactTransform = false
Step 5: Initialize ApxorSDK
To start tracking with the Apxor Android SDK, you must first initialize it.
Make Sure to enter the AppID for $APXOR_ID
You will need your Application Identifier for this. Here is how you can get the Apxor Application Identifier, as mentioned in the Integration Essentials section
You are all set: Verify your SDK integration
We have to verify two things as follows :
SDK Initialization
On running your Android project, search for the following log in logcat :
ApxorSDK(v2**) successfully initialized for: APP_ID

Plugin Initialization
By default, only error logs are enabled. To see debug logs for plugin initialization and to confirm tracking event triggers and user properties, Please run the below command in the terminal
adb shell setprop log.tag.Apxor VERBOSE

Add-Ons
Now that you have completed the basic integration, you can proceed to set up event triggers, capture data for targeting, add slots for embed cards and stories, and personalize messaging. Include the following sections as needed.
Identifying Users
The Apxor SDK automatically captures device IDs, and this is used to identify users uniquely by Apxor. Apart from this, you can log a custom user identifier that you use to uniquely identify users in your app.
This identifier would be very instrumental, especially when exporting data of a certain campaign or survey to your analytics system to create a cohort and measure the results of the campaign.
Similarly, when you are importing data to Apxor from your system that your marketing/product/data science team has identified and wants to run campaigns specifically for them, the custom user identifier will serve as the bridge to communicate between your systems and Apxor effectively.
Here is how you can set your user identifier for Apxor to recognize your users :
ApxorSDK.setUserIdentifier(<SOME_USER_ID>);
Here is how you can fetch the Apxor device identifier, which is automatically captured and maintained by the SDK if you want to record and map it to your data.
String deviceId = ApxorSDK.getDeviceId(applicationContext);
Log events and user data for Targeting, Triggering and goal Tracking
The product/marketing or the growth team lists the use cases with an idea of when and to whom to launch. To do this, we need to capture data in the form of events. Let us consider the following use case as an example:

App Events
In the above scenario, we want to trigger the campaign for users who have spent 'x' seconds and haven't tapped on a product. To understand that if the user has tapped the product, we should log an event along with its attributes as follows to capture data:

Similarly, if you want to send promotions to users who have viewed at least five products of the category shoes in the last three days or you want to measure how many people added an item to a cart from the campaign as a goal, all this information is captured in the form of events.
These types of events are classified as app events - the data that is transferred to the servers at Apxor, where you can segment users based on historical behaviour or measure your goals as specified above.
Here is how we track app events :
Attributes additionalInfo = new Attributes();
additionalInfo.putAttribute("ProductName", "MixerGrinder");
additionalInfo.putAttribute("ProductPrice", 2999);
ApxorSDK.logAppEvent("ProductClicked", additionalInfo);
Client Events
In the below scenario, let's assume you want to launch a survey when the soft back button is pressed asking the user for product feedback. In this, we don't need to capture the data of how many people pressed the back button, which is useless and bloats your event storage as it is a high-frequency event, which increases your cost unnecessarily. This data point doesn't potentially answer any of your product questions, and hence, there is no ROI in storing data from this event.
So for such scenarios where we need the behavioural data to launch a campaign or to collect feedback, which doesn't provide ROI on storing for measuring goals, answering your product questions or segmenting your target audience, we log these events as Client Events, which involves zero transfer of data and is used only to set up your triggers on behavioural information from the user.

Attributes additionalInfo = new Attributes();
additionalInfo.putAttribute("Screen", "com.example.app.SettingsActivity");
ApxorSDK.logClientEvent("SoftBackPressed", additionalInfo);
User Attributes
We can personalize the messaging copy in the experiences we build for the user or target based on his persona using information that is centric to individual users.
Let us consider the following example where we know the user prefers English as a language and has a Gold membership. This information helps to tailor content in English to that specific user and gives us the flexibility to use different messaging for different membership tiers. This is how the information captured here is used for segmenting.
Similarly, capturing attributes like Name, can you help to personalize your message copy where it reads "Hi {username} can't find your product?" where the username is replaced by the attribute value of the property from the nudges dashboard along with providing meaningful defaults in their absence.

This is how you log user information to Apxor :
Attributes userInfo = new Attributes();
userInfo.putAttribute("Name", "Prabhu");
userInfo.putAttribute("AcquistionSource", "Facebook");
userInfo.putAttribute("CampaignAttribution", "shoes-adset");
userInfo.putAttribute("UserGender", "Male");
userInfo.putAttribute("MembershipType", "Gold");
userInfo.putAttribute("AppLanguage", "English");
ApxorSDK.setUserCustomInfo(userInfo);
Session Attributes
A Session can be simply defined as a user's journey from when he opens the app until he closes the app. There can be various pieces of information that be very impactful when accumulated in a session. For example, location in a session can be useful to know exactly where the user is utilizing the app most.
To add session attributes that are specific to a session,
ApxorSDK.setSessionCustomInfo("network", "4G");
Or if you have multiple key-value pairs that need to be logged, you can simply put them in a hashmap like,
Attributes sessionInfo = new Attributes();
sessionInfo.putAttribute("network", "4G");
sessionInfo.putAttribute("city", "GAJ");
ApxorSDK.setSessionCustomInfo(sessionInfo);
Track Screens
In the scenario discussed in this guide, how will we know if the user has spent thirty seconds on the home screen and did not click on the product? For this reason, it is important to track the screens to set them up as triggers and also to capture the time spent on the screens.

Please ensure the following if you have fragments:
If your screen has different fragments, then it is important to track all the fragments using the API once the screen is visible to your user
If you use Android's Navigation architecture component, you can use
ApxorSDK.trackScreen
API inNavController.OnDestinationChangedListener
callbackIf your activity has different tabs either at the top or bottom, you can call
ApxorSDK.trackScreen
API every time a tab gets selected, as shown below:
By using the following API to track the screens in the app, you can set campaigns on inactivity or time spent on those screens:
ApxorSDK.trackScreen("HomeScreen");
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_share:
ApxorSDK.trackScreen("Share");
// Your logic
break;
case R.id.action_settings:
ApxorSDK.trackScreen("Settings");
// Your logic
break;
//.. other cases
}
}
});
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
ApxorSDK.trackScreen(tab.getText().toString());
// Your logic
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
// Your logic
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
// Your logic
}
});
Nudges in WebView
Tooltips in WebView
Many native applications feature WebView
s to display descriptive content and much more. Apxor Android SDK provides a way to show tooltips inside that WebView
to make the most of it.
Following are the steps in order to show tooltips in your WebView
.
Add a tag to the
WebView
(which is to be later provided in the dashboard) as shown.webView.setTag("MyWebView");
Attach Apxor SDK JavaScript Interface as mentioned below.
// You must enable Javascript for the webview WebSettings settings = webView.getSettings(); settings.setJavaScriptEnabled(true); // Attach Apxor SDK Javascript Interface webview.addJavascriptInterface(new ApxorJSInterface(), "Apxor");
That's it. All you have to do is set some IDs for your HTML elements inside your web page and configure them in the dashboard along with WebView's tag.
Log Events inside WebView
It is suggested that you log events inside your WebView once the page is completely rendered using Apxor JavaScript Interface methods. Based on these events, you can configure Tooltips.
Methods exposed from Apxor JavaScript Interface
window.Apxor.logAppEvent(event_name[, event_props]); window.Apxor.logClientEvent(event_name[, event_props]);
Examples for logging App Event
Example:
Log an event on page load event.
... <head> ... <script> function logApxorEvent(eventName, attributes) { if (window.Apxor && window.Apxor.logAppEvent) { window.Apxor.logAppEvent(eventName, attributes); } } </script> </head> <body onload="logApxorEvent('PageLoaded')"> ... </body>
Example (React based web pages):
Log an event on componentDidMount.
componentDidMount() { if (window.Apxor && window.Apxor.logAppEvent) { window.Apxor.logAppEvent('LoginPageLoaded', null); } }
Embed and Story Slots
Add Embed Card Slot
Note
For using Embed Cards, the versions of the following plugins should be greater than or equal to the ones mentioned below
Core: 3.1.0
qe: 1.7.5
rtm: 2.4.8
WYSIWYG: 1.5.6
For using Apxor's Embed cards template, this step is necessary.
In all areas of the app where you may want to show an in-line widget, insert the following code in the XML
<com.apxor.androidsdk.plugins.realtimeui.ApxorWidget
android:tag="<Tag>"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Rename <Tag> to any unique ID. Ensure that you keep the ID unique across different IDs and across different ApxorWidget instances.
Alternatively, you can also add the view dynamically during runtime. Make sure the widget is in a place where it can occupy the entire width and height as per its requirement.
ApxorWidget widget = new ApxorWidget(context,"<Tag>")
layout.addView(widget);
Add Story Slot
Note
For using Stories, the versions of the following plugins should be greater than or equal to the ones mentioned below
Core: 3.1.0
qe: 1.7.5
rtm: 2.4.8
WYSIWYG: 1.5.6
For using Apxor's Stories template, this step is necessary.
In all areas of the app where you may want to show an in-line widget, insert the following code in the XML
<com.apxor.androidsdk.plugins.realtimeui.stories.ApxorStoryWidget
android:tag="<Tag>"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Rename <Tag> to any unique ID. Ensure that you keep the ID unique across different IDs and across different ApxorWidget instances.
Alternatively, you can also add the view dynamically during runtime. Make sure the widget is in a place where it can occupy the entire width and height as per its requirement.
ApxorStoryWidget widget = new ApxorStoryWidget(context,"<Tag>")
layout.addView(widget);
Handle custom redirection using Key-Value pairs
If your app wants to redirect users based on simple key-value pairs instead of using Deeplink URLs or Activity, you can follow the below approach
import android.app.Application;
import com.apxor.androidsdk.core.ApxorSDK;
import com.apxor.androidsdk.core.RedirectionListener;
import org.json.JSONArray;
public class MyApplication extends Application {
@Override
public void onCreate() {
// Register a redirection listener ONLY ONCE in your app
// If you register in multiple places, ONLY the last value will be available.
// Whenever you register a new one, it will override the existing listener
Apxor.setRedirectionListener(new RedirectionListener() {
@Override
public void onActionComplete(JSONArray keyValuePairs) {
int length = keyValuePairs.length();
/**
* [
* {
* "name": "YourKey",
* "value": "YourValue"
* },
* ....
* ]
*/
try {
for (int i = 0; i < length; i++) {
JSONObject pair = keyValuePairs.getJSONObject(i);
String key = pair.getString("name");
// Values are always String type. You need to convert based on your need
String value = pair.getString("value");
// Your logic continues from here
}
} catch (JSONException e) {
}
}
});
}
}
Miscellanious
Reporting Custom Errors
Custom errors describe situations like LOGIN_FAILED and NETWORK_CALL_FAILED and are to be treated differently compared to app events. So, these are treated as errors and are shown on the issues page to let you know their impact.
A custom error takes the exception itself and some context (what? OR which?) to make it easy for you to identify. To report a custom error,
Exception e = new Exception("LOGIN FAILED EXCEPTION");
HashMap<String, String> additionalInfo = new HashMap<>();
additionalInfo.put("email", "[email protected]");
additionalInfo.put("cause", "network failure");
ApxorSDK.reportCustomError("Null Value", additionalInfo, e);
To get Apxor Device Identifier
Apxor SDK maintains a unique ID for every user. To get the Apxor Device ID, use the below
String deviceId = ApxorSDK.getDeviceId(applicationContext);
To get Apxor Attributes
Now you can use getAttributes
API to get the user and session attributes from ApxorSDK in a single API call.
Note:
This is an asynchronus call. So, you have to pass a callback. For that you can use
ApxorDataCallback
. There are two methods in this interface. One isonSuccess
andonFailure
. Both these methods will be called in a separate background thread.
ApxorSDK.getAttributes(
new String[]{ "custom_user_id", "email" },
new ApxorDataCallback() {
@Override
public void onSuccess(JSONObject props) {
if (props == null) {
return;
}
String userId = props.optString("custom_user_id");
String email = props.optString("email");
}
@Override
public void onFailure() {
Log.e(TAG, "Failed to get attributes");
}
}
);
Last updated