Android SDK Implementation Guide

Getting Started with Android

Specific configuration IDs and attribute code names are required to process app data into your Salesforce DMP account. Contact your Salesforce DMP representative for this information:

  • Follow instructions to download the Salesforce DMP aar from here
  • site Config id
  • exact attribute code names
  • event uids (if needed)
  • Google DFP custom key name (if needed)

Android Studio Setup

 

The Salesforce DMP Android SDK manages creation of the Salesforce DMP objects.

To initialize the library, call KruxEventAggregator.initialize() in onCreate() method of the main Activity (or Application) like this:

public class MyActivity extends Activity { 
@Override
public void onCreate() {
super.onCreate();
KruxSegments kruxSegmentsCallback = new KruxSegments() {
@Override
public void getSegments(final String segments) {
// Do something with segments.
}
};

private final static String _configid = "copy_from_krux_ui";
KruxEventAggregator.initialize(this, _configid, kruxSegmentsCallback , true); 
// Your code here.
}
}

getSegments

When a device meets specific rules of a segment created in the DMP, a segment ID will be returned and can be utilized for content optimization or ad targeting.  Use the getSegments method to store and send user segments for activation.

Note:  Segments must be explicitly selected in the Salesforce DMP UI to be returned.  This is the same requirement as for browser users

public static void kruxInit() 
KruxSegments kruxSegmentsCallback = new KruxSegments() {
@Override
public void getSegments(final String segments) {
Log.d(TAG, "Krux formatted segments: " + segments);
mSegments = segments;
}
};
KruxEventAggregator.initialize(context, _publisherConfigId, kruxSegmentsCallback, true);
}

KruxEventAggregator.initialize()

KruxEventAggregator.initialize() has the following parameters:

KruxEventAggregator.initialize(Context context, String configId, KruxSegments kruxSegmentsCallback, boolean debug);

context

Interface to global information about an application environment. It allows access to application-specific resources and classes, as well as calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.

configid

Salesforce DMP will provide every app with a unique Config id. You should use this Config id to initialize the SDK. If you initialize without Config id or use the wrong Config id, you will not be able to send data to Salesforce DMP servers. The Config id is a string between 8-10 characters in length and can contain lowercase and uppercase letters, digits, underscores, and dashes.

For help with the Config id please contact your contact your Salesforce DMP representative.

kruxSegmentsCallback

The SDK makes a call to the Salesforce DMP config service to obtain the Segments for a Config id. Specify a callback using this parameter if you need to use two segments, for example, when loading a Google Publisher Ad. Please refer to the Salesforce DMP test app for an example of this.

debug

Boolean flag that enables debug logs from KruxEventAggregator. This enables debug messages in logcat while it is trying to fetch data/send data to Salesforce DMP backend servers. You should turn this off before the final submission of your app.

Add Google Play Mobile Ads SDK and Salesforce DMP Android SDK dependencies in the app build.gradle file.

dependencies { compile 'com.google.android.gms:play-services-ads:9.2.0’ }


Add the following to the AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<service android:name="com.krux.androidsdk.aggregator.EventPublisherService" android:enabled="true" />
<service android:name="com.krux.androisdk.aggregator.ConsentService" android:enabled="true" /> 

The Google Play Advertising ID is used to uniquely identify your device. This id is sent back to Salesforce DMP during a trackPageView or fireEvent call. The logic around sending this id back to Salesforce DMP is:


a. If Google Play services is available and the user has not opted out of ad tracking, then the advertising id is sent to Salesforce DMP.
b. If Google Play services is available and the user has opted out of ad tracking, then 'OPTOUT' is sent to Salesforce DMP.
c. "android.permission.ACCESS_FINE_LOCATION" can be used in place of ACCESS_COARSE_LOCATION for more accurate lat/long data to be sent.

Sending data to Salesforce DMP from an Android app

KruxEventAggregator exposes two methods of sending data to Salesforce DMP servers. All calls are made asynchronously and will not impact the latency and stability of the core mobile app. All data is sent using a queuing approach to ensure that the calls are queued up when the user is not connected. Queued data sends when the user gets connected.

In the Salesforce DMP Platform, all apps will be displayed as "sites".

TrackPageView in Android

KruxEventAggregator.trackPageView(final String pageUrl, final Bundle pageAttributes, final Bundle userAttributes)

The trackPageView method sends data based on the actions users are performing on your apps. Specify string in the first parameter to describe the app and a set of attributes that they want Salesforce DMP to track.

The URL sent is shown as a “section” in Salesforce DMP and the attributes are displayed as page or user attributes.

Example News-Based App in Android Using Salesforce DMP

For example, if a news-based app is used, send Salesforce DMP information about the category of news being read by users. For users who log in to the app, also send their login id.

Call the trackPageView method whenever there is data to send to Salesforce DMP.

Below are some examples for illustrative purposes only. Your calls may depend on the kinds of data you want to send to Salesforce DMP.

For the news-based app case mentioned above, call trackPageView at the following places:

  1. User opens the Android App, and sees its splash screen.
    Bundle pageAttributes = new Bundle();
    Bundle userAttributes = new Bundle();


    pageAttributes.putString("action","open_app");

    KruxEventAggregator.trackPageView("page_name", pageAttributes, userAttributes);

  2. User reads an "Entertainment" Article in the Android App
    Bundle pageAttributes = new Bundle();
    Bundle userAttributes = new Bundle();


    pageAttributes.putString("article_read","Entertainment");

    KruxEventAggregator.trackPageView("page_name", pageAttributes, userAttributes);
  3. User logs in and reads a "Sports" Article in the Android App
    Bundle pageAttributes = new Bundle();
    Bundle userAttributes = new Bundle();


    userAttributes.putString("email_sha256","b33bf8d65c8ae5cf0e9e3bf5a222d97099cf32119bd5ed70769496d6ebcc3427");

    KruxEventAggregator.trackPageView("page_name", pageAttributes, userAttributes);

PLEASE NOTE: If you wish to pass more than one attribute value to a single attribute in the pixel call, please make sure the values are comma-separated when passing them.

FireEvent in Android

Events track specific user interactions.  This data is used as parts of an event funnel, where users follow a sequence of events to a goal.  A very common funnel would be steps to purchase an item, starting from app open.

Create events in Salesforce DMP under "People > Actions - Manage Events" and then use the fireEvent method to send information about an event to Salesforce DMP. The first parameter of this method should have the unique id of the event.  See ID column or the event, not name.

If the event contains attributes, you can send its name and values in this method call. 

KruxEventAggregator.fireEvent(String eventUid, Bundle eventAttributes)

For example, to fire this event every time someone goes to a new article category.  The code below shows how to accomplish this.

Create an event with id ‘HsdfRt12,’ in https://console.krux.com/events/list and create an event attribute called ‘article_category’ for all section names. 

Bundle eventBundle = new Bundle();
eventBundle.putString("event_id", "YOUR_EVENT_ID");
eventBundle.putString("article_category","news");
KruxEventAggregator.fireEvent("event_uid", eventBundle );

NOTE: "event_id" and the confID is mandatory for all fireEvent calls.

transaction in Android

Salesforce DMP has functionality to process detailed values for  price, quantity, dates and others attributes common for purchases.  See description and requirements for Transaction segments.

Do not attempt to send transaction data until your Salesforce DMP representative has verified that this feature has been enabled to your account.   Data will not be processed until it is on.

If you are collecting transaction data web sites, check with Salesforce DMP on the exact attribute names to use. Call transaction after a successful conversion:

Bundle transactionBundle = new Bundle();
transactionBundle.putString("price","$30");
transactionBundle.putString("quantity", "10");
transactionBundle.putString("orderDate", "2080-12-05");

KruxEventAggregator.transaction(transactionBundle);

Consent Capture, Lookup, Consumer Remove, & Portability

This documentation supports SDK specific enhancements made as part of feature releases to support Consumer Rights Management. Please read supporting documentation on Consumer Rights Management features on Zendesk, here.

Many data protection and privacy regulations require you and your company to obtain consent from users before collecting data about them, to honor users' requests for how you use their data, to honor users’ right to be forgotten and to export users’ personal data when users request it. The SDK includes the following four methods as it relates to consent and consumer requests:

void consentSetRequest(Bundle consentSetAttributes);
void consentGetRequest(Bundle consentGetAttributes);
void consumerRemoveRequest(Bundle consumerRemoveAttributes);
void consumerPortabilityRequest(Bundle consumerPortabilityAttributes);

The consentSetRequest method accepts the following parameters:

Parameter Description
idt Identification Type
dt Device Type
idv Identification Value
pr Policy Regime
dc Data Collection
al Analytics
tg Targeting
cd Cross Device
sh Sharing Data
re ReIdentification

The consentGetRequest method accepts the following parameters:

Parameter Description
idt Identification Type
dt Device Type
idv Identification Value
pr Policy Regime

The consumerRemoveRequest and consumerPortabilityRequest methods accept the following parameters:

Parameter Description
idt Identification Type
dt Device Type
idv Identification Value

For additional information about the meaning of and supported values for these parameters, please consult the glossary of terms, here.

idt, dt and idv are user identification parameters that the DMP uses to manage Consumer Rights activities. Providing identification parameters is optional with the SDK; In absence of identification parameters, the SDK defaults to using idt=device and dt=aaid.

If any user identification parameters (idt, dt, or idv) are provided, the caller must provide all identification parameters. If any one of them is missing, the "Wrong Identification Parameters" error is returned through callback.

These methods are implemented in an asynchronous fashion. If you want to handle response and/or errors for these requests, please implement the KruxConsentCallback interface, and provide its object as a parameter while initializing the SDK.

The SDK will forward response/error for a particular consent request by calling one of the methods of this consent callback object. The SDK is backward compatible, so you do not need to change application code if you don’t want to handle consent/consumer response/error messages.

Response Messages

Please refer to Consent and Consumer Webservice documentation here for more detail.

Error Messages

There are various error conditions under which consent set/get request might not be processed. A few examples of these situations are network not available, and an SDK internal error. For all of these errors, there will be one single message forwarded to client application through callback implementation. That message is "Could not process consent/consumer request". If the consent service responds with an http error then that error will be forwarded to the application.

SDK in-memory consent management

  • SDK runs a scheduler to fetch consent values every 30 minutes. So, if the consent settings are set using e.g., file upload, then consent values will be updated correctly.
  • SDK is concerned only with the data collection field. Based on this value, it will decide whether to collect data or not.
  • SDK manages in-memory consent record. This consent record gets updated either by a scheduler or whenever user sets the consent values by calling consent set method.
  • SDK logs a warning message every 30 minutes if explicit consent via file upload, SDK interface, or an API call is not found.

Code snippet to call consent/consumer methods

public void sendRequests() {
Bundle consentSetAttributes = getConsentAttributes();
Bundle consentGetAttributes = getIdParameters();
Bundle idAttributes = getIdParameters();
addPolicyRegimeParameter(consentGetAttributes);
addPolicyRegimeParameter(consentSetAttributes);

KruxEventAggregator.consentGetRequest(consentGetAttributes);
KruxEventAggregator.consentSetRequest(consentSetAttributes);
KruxEventAggregator.consumerRemoveRequest(idAttributes);
KruxEventAggregator.consumerPortabilityRequest(idAttributes);
}

private void addPolicyRegimeParameter(Bundle attributes) {
attributes.putString("pr","gdpr");
}

private Bundle getIdParameters(){
Bundle attributeBundle = new Bundle();
attributeBundle.putString("idv","REPLACE_WITH_AAID_VALUE");
attributeBundle.putString("dt","aaid");
attributeBundle.putString("idt","device");
return attributeBundle;
}

private Bundle getConsentAttributes() {
Bundle attributeBundle = new Bundle();
attributeBundle.putInt("dc", 1);
attributeBundle.putInt("cd", 1);
attributeBundle.putInt("tg", 1);
attributeBundle.putInt("al", 1);
attributeBundle.putInt("sh", 1);
attributeBundle.putInt("re", 1);
return attributeBundle;
}

Code snippet for KruxConsentCallback Interface

public interface KruxConsentCallback {
void handleConsentGetResponse(String consentGetResponse);
void handleConsentGetError(String consentGetError);
void handleConsentSetResponse(String consentSetResponse);
void handleConsentSetError(String consentSetError);
void handleConsumerRemoveResponse(String consumerRemoveResponse);
void handleConsumerRemoveError(String consumerRemoveError);
void handleConsumerPortabilityResponse(String consumerPortabilityResponse);
void handleConsumerPortabilityError(String consumerPortabilityError);
}

Code snippet containing KruxConsentCallback implementation and providing its object to the SDK

public class KruxConsentCallbackImpl implements KruxConsentCallback {

private final static String TAG = KruxConsentCallbackImpl.class.getSimpleName();

@Override
public void handleConsentGetResponse(String consentGetResponse) {
Log.i(TAG,"Consent get response: "+consentGetResponse);
}

@Override
public void handleConsentGetError(String consentGetError) {
Log.i(TAG,"Consent get error: "+consentGetError);
}

@Override
public void handleConsentSetResponse(String consentSetResponse) {
Log.i(TAG,"Consent set response: "+consentSetResponse);
}

@Override
public void handleConsentSetError(String consentSetError) {
Log.i(TAG,"Consent set error: "+consentSetError);
}

@Override
public void handleConsumerRemoveResponse(String consumerRemoveResponse) {
Log.i(TAG,"Consumer remove response: "+consumerRemoveResponse);
}

@Override
public void handleConsumerRemoveError(String consumerRemoveError) {
Log.i(TAG,"Consumer remove error: "+consumerRemoveError);
}

@Override
public void handleConsumerPortabilityResponse(String consumerPortabilityResponse) {
Log.i(TAG,"Consumer portability response: "+consumerPortabilityResponse);
}

@Override
public void handleConsumerPortabilityError(String consumerPortabilityError) {
Log.i(TAG,"Consumer portability error: "+consumerPortabilityError);
}
}
  public void kruxInit() {
KruxSegments kruxSegmentsCallback = new KruxSegments() {
@Override
public void getSegments(final String segments) {
Log.d(TAG, "Krux formatted segments: " + segments);
mSegments = segments;
}
};
KruxConsentCallback consentCallback = new KruxConsentCallbackImpl();
KruxEventAggregator.initialize(context, "REPLACE_WITH_YOUR_CONFID", kruxSegmentsCallback, true, consentCallback);
}

Debugging/Testing in Android

See "Testing Your SDK Integration" and "Verifying the SDK Implementation with Charles Proxy" for more on how to test and verify your Salesforce DMP mobile app SDK implementation.

Have more questions? Submit a request

0 Comments

Article is closed for comments.