Permutive Developer Hub

Welcome to the Permutive developer hub. You'll find comprehensive guides and documentation to help you start working with Permutive as quickly as possible, as well as support if you get stuck. Let's jump right in!

API Reference

The Android SDK is comprised of one core SDK, and several kit libraries integrating with other 3rd Party SDKs.

Using multiple kit libraries enables feature-rich integration with minimal effort for developers and greater benefits to our clients.

The Android SDK is currently in Beta. If you would like to use this SDK, please talk to your customer support manager.

Download

To include in your Android application, add the following line to your dependencies:

implementation "com.permutive.android:core:0.2.5"

Initialise the SDK

The SDK requires that you provide it with a Project ID and API Key - which are available from the dashboard. None of the other functionality of the SDK is available until these are passed in.

The Permutive object should be created only once, we suggest initialising this in your application's onCreate method, or defining as a singleton in your DI graph.

Construction of the Permutive object is quick - it won't cause any issues with framerate drops. You can start making permutive calls straight away.

import com.permutive.android.Permutive
//..

  override fun onCreate() {
    //..
    val permutive = Permutive(context = this,
                              projectId = YOUR_PROJECT_ID,
                              apiKey = YOUR_API_KEY)
  }
import com.permutive.android.Permutive;

//..

  @Override
  void onCreate() {
  //..
    final Permutive permutive = new Permutive.Builder()
                                        .context(this)
                                        .projectId(YOUR_PROJECT_ID)
                                        .apiKey(YOUR_API_KEY)
                                        .build()
  }

Identity Management

You can set a custom identity for the user, whenever it's available. This may be appropriate when users login to your app, and a custom identity such as an internal identifier or email address may be available. Identifying a user with a custom identity is useful if you want to identify and synchronise users across platforms, for example across Android and web.

You can start the Permutive SDK with an optional identity, if you have this:

  val permutive = Permutive(context = this,
                              projectId = YOUR_PROJECT_ID,
                              apiKey = YOUR_API_KEY,
                              identity = "android@permutive.com")
    final Permutive permutive = new Permutive.Builder()
                                        .context(this)
                                        .projectId(YOUR_PROJECT_ID)
                                        .apiKey(YOUR_API_KEY)
                                        .identity("android@permutive.com")
                                        .build()

Or you can call setIdentity at any point after the Permutive SDK has been created.

Permutive.setIdentity("android@permutive.com")

To integrate automatically with the device's AAID (or GAID) - please read information on Tracking AAID identities below.

Event Tracking

Events represent any activity in your application worth tracking. Examples include entering and leaving view, engagement changes (i.e. scrolling inside an article) and any other user or environment driven inputs.
To track an event, grab an instance of eventTracker object - and call the track method. Event tracking can include properties passed in as a map.

Please note: event names should only contain characters in [a-zA-Z0-9_], and property names should only contain characters in [a-z0-9_]. Any character outside the allowed character set will result in an IllegalArgumentException.

As with all other Permutive SDK APIs, the event tracker object is lightweight and multiple instances of it can be created, as needed. Event tracking is thread-safe, so feel free to track events from any thread. It is also asynchronous, and so will not block.

Adding Context

Just like on the web, you can add extra context to the events you are tracking. You can set values for url, title and referrer. The domain is automatically inferred from url, if it has been set. Subsequent calls to track will contain the extra context as part of the event properties, within a client object. The context is persisted between application instances.


with(permutive.eventTracker()) {      
    track("app launched", EventProperties.from("first_time" to true))

    //or with no properties
    track("app started")

    permutive.setTitle("Android Tutorial")
    permutive.setUrl(Uri.parse("http://www.permutive.com/android/tutorials"))
    permutive.setReferrer(Uri.parse("http://www.permutive.com/android/tutorials?referrer=johnDoe"))

    //contains url/title/referrer & domain context implicitly
    track("page viewed")      
}
final EventTracker eventTracker = permutive.eventTracker();

eventTracker.track("app launched",
                         new EventProperties.Builder()
                             .with("first_time", true)
                             .build())

eventTracker.track("app started")

permutive.setTitle("Android Tutorial")
permutive.setUrl(
    Uri.parse("http://www.permutive.com/android/tutorials"))
permutive.setReferrer(
    Uri.parse("http://www.permutive.com/android/tutorials?referrer=johnDoe"))

//contains url/title/referrer & domain context implicitly
eventTracker.track("page viewed")

Event Enrichment

To pass through geographic or ISP information for your custom events, you can pass through a special value when tracking the event:

val eventTracker = permutive.eventTracker()

with(eventTracker) {
  track("eventX",
        EventProperties.from(
            "my_geo_info" to EventProperties.GEO_INFO,
            "my_isp_info" to EventProperties.ISP_INFO))
}
final EventTracker eventTracker = permutive.eventTracker();

final EventProperties eventProperties =
    new EventProperties.Builder()
        .with("my_geo_info", EventProperties.GEO_INFO)
        .with("my_isp_info", EventProperties.ISP_INFO)
        .build()

eventTracker.track("eventX" , eventProperties)

The event will be enriched to (for example):

{
    "my_geo_info": {
        "city": "Ayr",
        "continent": "Europe",
        "country": "United Kingdom",
        "postal_code": "KA7",
        "province": "South Ayrshire"
    },
    "my_isp_info": {
        "autonomous_system_number": 2856,
        "autonomous_system_organization": "British Telecommunications PLC",
        "isp": "BT",
        "organization": "BT"
    }
}

This also applies to any values that are deeper in the properties tree (since properties can contain other Map<String, Any> objects as values).

If at the time no geo or isp information is available, these properties are stripped from the event information.

Segment Query

To track what segments the user belongs to, you can use the API call below. The callback will be called straight away with the current segments the user is in, and then called each time the segment list changes. Segments are returned as a list of Integers. These correspond to segment IDs setup in the Permutive Dashboard. The returned list is never null.

val triggersProvider = permutive.triggersProvider()
val segmentsTriggerAction = 
    triggersProvider.querySegments{ segments: List<Int> ->
                                     segments.forEach{
                                       log("The user is in segment: $it")
                                     }
                                   }

//when you wish to stop tracking changes, close the action
segmentsTriggerAction.close()
final TriggerProvider triggerProvider = permutive.triggerProvider();
final TriggerAction action =
    triggerProvider.querySegments(segments -> {
        for (int segment : segments){
            log("The user is in segment: "+segment)
        }
    });

Tracking Segment and Query Changes

To track real time changes to any queries, or segments, the developer can use trigger actions. Trigger actions contain a callback that is called immediately with the current value of that query/segment, and then each time that value changes. The value is never null. Please be aware that the callback may be called from a different thread than the one setting it up.

When you wish to stop receiving updates, call close on the trigger action. Not calling close on a trigger action may result in context leaks, it's a good idea to close any actions that are associated with your android component at an appropriate point in it's lifecycle (say for an Activity, at it's onPause/onStop callbacks).

Segments are always of type Boolean - so it is appropriate to use the triggerAction<Boolean> for these. Queries can be of a simple type - Boolean, String, Int, Long, Float, Double, or a more complex type: Map<String, Any> (where Any is of any of the simple types, or another Map of type <String, Any>).

If a query Id does not exist, the trigger will still be created, but the callback will never be called. If, however, the query does exist at a later point (the SDK may fetch a fresher version of the queries), then the callback will be called when a value is present, and then for each time the value changes.

Using a wrong type for a given query Id will immediately log an error to the console. The callback will never be called.

val triggersProvider = permutive.triggersProvider()

val triggerAction = 
    triggersProvider.triggerAction<Boolean>(queryId = 1) {
        log("Query 1 change: $it") //it is Boolean
    }

//when you wish to stop tracking changes, close the action
triggerAction.close()

val triggerActionMap = 
    triggersProvider.triggerActionMap(queryId = 2) {
        log("Query 2 change: $it") //it is Map<String,Any>
    }
final TriggersProvider triggersProvider = permutive.triggersProvider();

final TriggerAction triggerAction =
    triggersProvider.triggerAction(1, 
        value -> log("Query 1 change: "+value)); //value is Boolean

//when you wish to stop tracking changes, close the action
triggerAction.close()

final TriggerAction mapAction =
    triggersProvider.triggerActionMap(2,
        value -> log("Query 2 change: $it")); //value is Map<String,Any>

Tracking reactions

Tracking reactions is very similiar to tracking segment changes, once you register a listener, you will get the initial state, and on each change you will get an update until you close the trigger action.

val triggersProvider = permutive.triggersProvider()
val dfpReactionsTriggerAction = 
    triggersProvider
        .queryReactions("dfp"){ segments: List<Int> ->
                                segments.forEach{
                                  log("The user is in segment: $it")
                                }
                              }

//when you wish to stop tracking changes, close the action
dfpReactionsTriggerAction.close()
final TriggerProvider triggerProvider = permutive.triggerProvider();
final TriggerAction action =
    triggerProvider.queryReactions("dfp",segments -> {
        for (int segment : segments){
            log("The user is in segment: "+segment)
        }
    });

We have provided an easy way to add targeting for google ads requests. See the google-ads library instructions below.

Tracking AAID identities

In addition to identifying your user via a custom identity, you can also automatically track a user by their AAID. To do this, just include the google-ads dependency in your gradle build:

implementation "com.permutive.android:google-ads:0.2.5"

When creating the permutive object, simply add the AaidAliasProvider to the alias providers:

import com.permutive.android.Permutive
//..
  overide fun onCreate() {
  //..

      val permutive = Permutive(context = this,
                                projectId = YOUR_PROJECT_ID,
                                apiKey = YOUR_API_KEY,
                                aliasProviders = listOf(AaidAliasProvider(this))
  }
import com.permutive.android.Permutive;
//..

  @Override
  void onCreate() {
  //..

    final Permutive permutive =
        new Permutive.Builder()
            .context(this)
            .projectId(YOUR_PROJECT_ID)
            .apiKey(YOUR_API_KEY)
            .aliasProvider(new AaidAliasProvider(this)
            .build()
  }

The AAID will be tracked automatically by the SDK as soon as it is available.

Custom targeting with Google Ads

We provide an easy way to add custom targeting of your Permutive reactions to your google ads requests. To do this:

//To add custom targeting
val adRequest1 = 
            PublisherAdRequest.Builder()
                .addPermutiveTargeting(permutive)
                .build()

//Or simply without the build call:
val adRequest2 = 
        PublisherAdRequest.Builder()
            .buildWithPermutiveTargeting(permutive)
//In Java, you can use PermutiveAdRequestBuilder as a replacement
//for PublishAdRequest.Builder.
//PermutiveAdRequestBuilder has the same interface as
//PublishAdRequest.Builder
PublisherAdRequest request1 =
    new PermutiveAdRequestBuilder(permutive)
        .build();

//Or you can use the static methods to add permutive targeting
//to your existing PublisherAdRequests
PublishAdRequest.Builder builder =
    new PublisherAdRequest.Builder();

//to add custom targeting:
builder = PublisherAdRequestUtils
            .addPermutiveTargeting(builder, permutive);

//to add and build:
PublishAdRequest request2 = 
    PublishAdRequestUtils
        .buildWithPermutiveTargeting(builder, permutive);

Android


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.