Android

Integration


The following steps outline the integration of the Upsight SDK for ad mediation.

First, add the Upsight repository to your application's build.gradle.

allprojects {
    repositories {
        maven {
            url "https://nexus.upsight.com/nexus/content/repositories/upsight-android-release/"
        }
        ...
    }
}

To include all the standard Upsight modules, add:

compile 'com.upsight.android:all:4.2.3'
compile 'com.upsight.android:mediation:4.2.3'

Add the following in your application Manifest. The application token and public key are provided on the Upsight Dashboard under Settings > Applications > "YOUR_APPLICATION_NAME".

<application>

    <!-- Application token and public key from Upsight Dashboard -->
    <meta-data
        android:name="com.upsight.app_token"
        android:value="UPSIGHT_APPLICATION_TOKEN" />
    <meta-data
        android:name="com.upsight.public_key"
        android:value="UPSIGHT_PUBLIC_KEY" />

    <!-- e.g. android:authorities="com.yourCompany.yourApplication.upsight" -->
    <provider
        android:name="com.upsight.android.internal.persistence.ContentProvider"
        android:authorities="APPLICATION_PACKAGE_NAME.upsight"
        android:enabled="true"
        android:exported="false" />
</application>

In order to access any API from the SDK, the application needs to build an UpsightContext. This should be done in the onCreate() of your Application or Activity, so we begin tracking the session appropriately:

public class SampleActivity extends Activity {

    private UpsightContext mUpsight;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        // Create an UpsightContext from any Android Context.
        mUpsight = Upsight.createContext(this);
        ...
    }
}

If you wish to enable logging, add the following:

mUpsight.getLogger().setLogLevel(Upsight.LOG_TAG, EnumSet.allOf(UpsightLogger.Level.class));

Tip: You may call Upsight.createContext(android.content.Context) anywhere in your application, and as often as you need a reference to UpsightContext. The same instance will be returned on each call.

Tip: You can use UpsightContext anywhere in your application where you currently use an android.content.Context. It provides extra functionality made available by the Upsight SDK.

Tracking Paying Users


Tracking Paying Users

Upsight offers you the ability to track in-app purchase events, which not only provides you with revenue data in your dashboards, but also allows you to segment your users based on their spending behaviours.

If you wish to track an in-app purchase that is processed through the Google Play Store, use the following API from the UpsightGooglePlayHelper, which extracts receipt information for our servers to verify the transaction with Google:

UpsightGooglePlayHelper.trackPurchase(mUpsight, quantity, currency, price, totalPrice, product, responseData, publisherData);
  • mUpsight - The Upsight Context.

  • quantity - The number of products purchased during the transaction.

  • currency - The currency as a 3-character ISO 4217 code.

  • price - The price per unit in local currency.

  • totalPrice - The total price of the transaction, including fractional amounts of the currency, before store fees have been taken into account.

  • product - The product ID of the Google Play in-app product.

  • responseData - The purchase response data from onActivityResult(). See Google Play In-app Billing Version 3 API.

  • publisherData - Optional custom parameter bundle.

Note If you would like your IAP data to be validated, first upload your Google Play License Key to Upsight Dashboard.

App Settings Dashboard

This can be found by navigating to the Upsight Dashboard in the App Settings page. (Applications > YOUR_APPLICATION > App Settings > Edit App > Google Play License Key).

If you have a purchase to record that did not involve the Google Play store, you can use the following code below to record a Monetization Event, where no receipt verification will be performed:

UpsightMonetizationEvent
    .createBuilder(totalPrice, currency)  // Required event properties.
    .setProduct("product.name")           // Optional event property.
    .put(customBundle)                    // Custom property bundle.
    .put(customKey, customValue)          // Custom property override.
    .record(mUpsight);                    // Record event.

Showing Mediated Video Ads


Milestones

Milestones track user movement through your app and allow you to manage exactly when and where a user sees marketing content, including mediated ads. Milestones are triggered when your user reaches a point in your application that you want to track or take action on.

The client tells the server that the user has reached a specific milestone in the application, by recording an UpsightMilestoneEvent as below:

UpsightMilestoneEvent.createBuilder(scope).record(mUpsight);

Milestones have one required property—a "Scope" that uniquely describes that location in your application. Examples of Scope are "main_menu", "inventory", or "level_up".


Important Milestones must also be setup in the Upsight dashboard. See Dashboard Setup for instructions.

Billboards

Displaying marketing content requires a "Billboard". A Billboard is like an empty frame into which the SDK can place content it receives from the server in response to a Milestone. Like Milestone events, each Billboard is associated with a Scope. Upon receiving an event, the server will send marketing content applicable to the Scope of that Milestone, which are eligible for the Billboard with matching Scope. This allows for control of when and where the content is created.

To create a Billboard, add the following to the onResume() of an Activity or Fragment:

UpsightBillboard.Handler handler = UpsightBillboardHandlers.forDefault(activity);
UpsightBillboard billboard = UpsightBillboard.create(mUpsight, scope, handler);

The Billboard created should be destroyed in the onPause() by calling billboard.destroy() to avoid unintended UI transitions. You cannot create two Billboards with the same scope unless the first one has been destroyed, or it has completed the lifecycle of displaying a unit of marketing content, in which case it is unregistered by the system and its handler.onDetach() callback has occurred.

The handler allows the client to be notified of Billboard lifecycle events when an eligible marketing content becomes available. The UpsightBillboardHandlers class provides default implementations, but the client may provide custom implementations by subclassing the defaults, or directly implementing the UpsightBillboard.Handler interface. For example, the client may wish to temporarily disable a Billboard. To accomplish this, return null when handler.onAttach() is called to skip over any marketing content that becomes available during that time.

Additionally, if you would like to check that content is ready to display before opening a billboard, you can use the isContentReady method. This method will only return true if milestone is invoked with the corresponding scope and content has been received from the server.

UpsightMarketingContentStore.isContentReady(mUpsight, scope)

Tip: The permission requirement android.permission.INTERNET is automatically merged to your application Manifest.

Rewarded Video Ads - Handling Rewards

In the event your user receives a reward, you are notified through this optional method from the UpsightBillboard.Handler:

void onRewards(List<UpsightReward> rewards);

By providing an implementation for this method, your code is given the opportunity to take appropriate action based on your user completing a rewarded video ad.

See below for a sample implementation of the onRewards methods.

private static class MyBillboardHandler extends UpsightBillboardHandlers.DefaultHandler {

    private final Context mContext;

    private MyBillboardHandler(Activity activity) {
        super(activity);

        // It is important that you do not keep a strong reference to the Activity, but only use
        // the Application Context in your callback implementations, because there is no
        // guarantee the current Activity will be present when these callbacks are triggered.
        mContext = activity.getApplicationContext();
    }

    @Override
    public void onRewards(List<UpsightReward> list) {
        for (UpsightReward reward : list) {
            String text = "Reward received: " + reward.getProduct() + " x " + reward.getQuantity();
            Toast.makeText(mContext, text, Toast.LENGTH_SHORT).show();
        }
    }
}

Validating Rewards

If you would like to validate the reward that the Upsight server has granted to the device, you can do so by sending reward signature data to your server and performing an operation on the contents. You can get the signature data JSON by calling UpsightReward.getSignatureData().

This JSON object contains the product, sid, quantity, nonce, and signature of the reward. You use the product, sid, quantity, and nonce along with your app's secret_key to produce the signature provided in the payload on your server.

Below is a python example of reward verification:

import base64
import hashlib
import hmac


def validate_signature_data(signature_data, secret):
    """Validates the signature for Upsight rewards.

    >>> secret = 'YOUR_32_CHAR_SECRET_KEY'
    >>> signature_data = {
    ...     'idfv': 'AAAAAAAA-0000-0000-0000-000000000000',
    ...     'nonce': '0437121572:rambo_cat:1',
    ...     'product': 'rambo_cat',
    ...     'quantity': 1,
    ...     'sid': '10000000000000000000',
    ...     'sig4': 'joQiupsyEe10Ui83TCPuScVBfOo',
    ...     'token': 'YOUR_APP_TOKEN'
    ... }
    >>> validate_signature_data(signature_data, secret)

    If the signature is invalid, or there is a problem with the signature_data
    dictionary, ValueError will be raised:

    >>> signature_data['sig4'] = 'invalid'
    >>> validate_signature_data(signature_data, secret)
    Traceback (most recent call last):
      ...
    ValueError: incorrect signature

    :param dict signature_data: A dictionary of signature data, from the SDK.
    :param str secret: Your app secret string.
    :raises ValueError: if the signature is invalid.
    """
    for required in ('nonce', 'sig4', 'token'):
        if required not in signature_data:
            raise ValueError('signature_data is missing {}'.format(required))

    identifiers = {}
    for identifier in ('device', 'gid', 'ifa', 'mac', 'odid', 'odin',
                       'idfv', 'sid'):
        value = signature_data.get(identifier)
        if not value:
            continue
        if isinstance(value, unicode):
            value = value.encode('utf8')
        identifiers[identifier] = value
    if not identifiers:
        raise ValueError('signature_data is missing identifiers')

    message = ':'.join((':'.join(str(identifiers[key])
                                 for key in sorted(identifiers.keys())),
                        signature_data['token'],
                        signature_data['nonce']))
    signature_hash = hmac.new(str(secret), message, hashlib.sha1)
    signature = base64.urlsafe_b64encode(signature_hash.digest()).rstrip('=')
    if not hmac.compare_digest(signature_data['sig4'], signature):
        raise ValueError('incorrect signature')

Dashboard Setup

In order to trigger ads in your app, you'll need to add milestones and rewards to your application settings in the Upsight dashboard, and create static interstitial, non-rewarded video, or rewarded video campaigns. See the Dashboard Setup section for details.