Advanced

General listeners

Loaded Tapdaq config

Called immediately after the SDK is ready to begin loading adverts. Create a subclass of TMInitListener and override the didInitialise() method.

public class TapdaqInitListener extends TMInitListener {

    @Override
    public void didInitialise() {
        super.didInitialise();
        // Ads may now be requested
    }
    
    @Override
    public void didFailToInitialise(TMAdError error) {
        super.didFailToInitialise(error);
        // Tapdaq has failed to initalise
    }
}

Next, instantiate the listener class when you initialise Tapdaq, like so:

Tapdaq.getInstance().initialize(this, "<APP_ID>", "<CLIENT_KEY>", config, new TapdaqInitListener());

Advert listeners

Loaded an advert

Called immediately after an interstitial is available to the user.

@Override
public void didLoad() {
    // ad has loaded
}

Supports: interstitial, video, rewarded video, banner, native ads

Loaded an advert

Called immediately after a mediate native ad is available to the user.

@Override
public void didLoad(TDMediatedNativeAd ad) {
    // ad has loaded
}

Supports: mediated native ads

Failed to load an advert

Called when the advert was not able to be loaded.

@Override
public void didFailToLoad(TMAdError error) {
    // failed to load an ad
}

Support: interstitial, video, rewarded video, banner, native ads

Refreshed an advert

Called when a banner refreshes

@Override
public void didRefresh() {
    // ad has refreshed
}

_Supports: banner

About to display an advert

Called immediately before the advert is to be displayed to the user.

@Override
public void willDisplay() {
    // ad will display
}

Supports: interstitial, video, rewarded video

Displayed an advert

Called immediately after the advert is displayed to the user.

@Override
public void didDisplay() {
    // ad did display
}

Supports: interstitial, video, rewarded video

Fail to Display an advert Called after show when ad is unavailable or unable to display.

public void didFailToDisplay(TMAdError error) {
    // ad failed to display
}

Supports: interstitial, video, rewarded video

Advert closed

Called when the user closes the advert.

@Override
public void didClose() {
    // interstitial closed
}

Supports: interstitial, video, rewarded video

User clicked an advert

Called when the user clicks the advert.

@Override
public void didClick() {
    // user clicked the interstitial
}

Supports: interstitial, video, rewarded video, banner, native ads

More apps listeners

More apps loaded

Called immediately after the more apps content is loaded Create a subclass of TMMoreAppsListener and override the didLoad() method.

public class MoreAppsListener extends TMMoreAppsListener {

    @Override
    public void didLoad() {
        // Ready to display more apps popup
    }

}

You can instantiate this listener class when loading and showing the More Apps popup, like so:

// To load..
Tapdaq.getInstance().loadMoreApps(<CurrentActivity>, new TMMoreAppsConfig(), new MoreAppsListener());

// To show..
Tapdaq.getInstance().showMoreApps(<CurrentActivity>, new MoreAppsListener());

More apps failed to load

Called when the more apps popup was not able to be loaded.

@Override
public void didFailToLoad(TMAdError error) {
    // failed to load more apps popup
}

More apps about to display to the user

Called immediately before the more apps popup is to be displayed to the user.

@Override
public void willDisplay() {
    // more apps will display..
}

More apps did display to the user

Called immediately after the more apps popup is displayed to the user.

@Override
public void didDisplay() {
    // more apps popup did display
}

More apps was closed

Called when the user closes the more apps popup.

@Override
public void didClose() {
    // more apps popup closed
}

Custom Events

For all other events, didCustomEvent will be called with a specialised data set for that event.

@Override
public void didCustomEvent(Map<Object, Object> eventData) {

}

Supports: offerwall

Rewarded video listeners

Received a reward for the user

Called when a reward is ready for the user.

@Override
public void didVerify(TDReward) {
    // user is rewarded
}

Failed to give a reward to the user

Called if an error occurred when rewarding the user.

@Override
public void didFail(TMAdError error) {
    // failed to give the user a reward
}

User did not want to watch the video

Called when the user did not want to watch the video.

@Override
public void onUserDeclined() {

}

Reward Id

The Reward Id is used for server-side callbacks, you can also retrieve it based on placement tags in the SDK like so:

Tapdaq.getInstance().getRewardId(tag);

Rewarded Video User Id

For server side callbacks, a Hashed User Id can be passed into the ShowRewardedVideo method, this will then be added to our server side callback to identify users.

NOTE: The String should be hashed before passed to Tapdaq SDK.

Tapdaq.getInstance().showRewardedVideo(<Activity>, "<Placement_Id>", "<Hashed_User_Id>", new TMAdListener());

Recommended permissions

This permission allows us to cache ads on external storage rather than internal which is likely smaller and more important. If you do not allow this, everything will still work the same but may annoy users if the internal storage fills up (despite our efforts to clear out of data cached data).

Android 5 and below Support

Add the following permissions to your AndroidManifest.xml file

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.company.name">

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application>
      ...
    </application>
</manifest>

Android 6 and above Support

It is up to you where in your app flow you'd like to do this, although ideally you should do this as early as possible.

Within an Activity create and call a method to request the permissions

private void requestPermissions() {
    // Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {

            // Show an expanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.

        } else {

            // No explanation needed, we can request the permission.

            ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);

            // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
    }
}

You may wish to override the onRequestPermissionsResult() method.

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case 100:
        {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //WRITE External Storage Granted
            } else {
                //WRITE External Storage failed
            }
            break;
        }
        default:
            break;
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

In App Purchase Tracking

Tapdaq & AppLovin can track your users In App Purchases, to pass the data do the following:

String name = ""; //Item Name
double price = 0.0; // Item Price
String currency = "GBP"; //3 Character currency code
Locale locale = Locale.getDefault(); //Locale of the device/store
Intent intent; //Intent returns by Play Store IAP activity

Tapdaq.getInstance().sendIAP(<CONTEXT>, intent, name, price, currency, locale);

//Alternatively retrieve the following data from the intent
String in_app_purchase_data = intent.getStringExtra("INAPP_PURCHASE_DATA");
String in_app_purchase_signature = intent.getStringExtra("INAPP_DATA_SIGNATURE");
Tapdaq.getInstance().sendIAP(<CONTEXT>, in_app_purchase_data, in_app_purchase_signature, name, price, currency, locale);

AdMob Targeting

As of Tapdaq SDK 7.0.0, an AdMob content rating will be forwarded for every ad request to AdMob, to do this, set the value in the config either before Tapdaq has initialised or after like so:

//Before Tapdaq initialises
TapdaqConfig config = new TapdaqConfig();
config.setAdMobContentRating("MA"); // G, PG, T, MA
config.setIsAgeRestrictedUser(true); // GDPR/COPPA flag

//After Tapdaq initialises
Tapdaq.getInstance().config().setAdMobContentRating("MA"); // G, PG, T, MA
Tapdaq.getInstance().config().setIsAgeRestrictedUser(true); // GDPR/COPPA flag

The tag_for_under_age_of_consent flag will be sent to AdMob if the user is subject to GDPR and AgeRestrictedUser is set. The ChildDirectedTreatment COPPA flag will be sent if user is not known to be subject to GDPR and AgeRestrictedUser is set. Read more about AdMob Targeting here.

ProGuard

Before enabling ProGuard in your app, you must add Tapdaq and other third party network configurations to your proguard-rules.pro file

#Tapdaq
-keep class com.tapdaq.sdk.** { *; }
-keep class com.tapdaq.adapters.* { *; }
-keep class com.tapdaq.unityplugin.* { *; }

#AdColony
# For communication with AdColony's WebView
-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}

# Keep ADCNative class members unobfuscated
-keepclassmembers class com.adcolony.sdk.ADCNative** {
    *;
}

# For removing warnings due to lack of Multi-Window support
-dontwarn android.app.Activity

#AdMob
-keep public class com.google.android.gms.ads.** {
    public *;
}

-keep public class com.google.ads.** {
    public *;
}

#Applovin
-dontwarn com.applovin.**
-keep class com.applovin.** { *; }
-keep class com.google.android.gms.ads.identifier.** { *; }

#Chartboost
-keep class com.chartboost.** { *; }

#Facebook Audience Network
-keep class com.facebook.ads.** { *; }

#HyprMX
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes *Annotation*
-keepattributes EnclosingMethod
-keep class com.hyprmx.** {*;}
-keep class okhttp3.hyprmx.** { *; }
-keep interface okhttp3.hyprmx.** { *; }
-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}
-dontwarn okhttp3.hyprmx.**
-dontwarn okio.hyprmx.**
-dontwarn com.google.android.gms.ads.identifier.**

#InMobi
-keepattributes SourceFile,LineNumberTable,InnerClasses
-keep class com.inmobi.** { *; }
-dontwarn com.inmobi.**
-keep class com.google.android.gms.common.api.GoogleApiClient { public *; }
-keep class com.google.android.gms.common.api.GoogleApiClient$* {public *;}
-keep class com.google.android.gms.location.LocationServices {public *;}
-keep class com.google.android.gms.location.FusedLocationProviderApi {public *;}
-keep class com.google.android.gms.location.ActivityRecognition {public *;}
-keep class com.google.android.gms.location.ActivityRecognitionApi {public *;}
-keep class com.google.android.gms.location.ActivityRecognitionResult {public *;}
-keep class com.google.android.gms.location.DetectedActivity {public *;}
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient{
     public *;
}
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient$Info{
     public *;
}
-dontwarn com.google.android.gms.**
# skip the Picasso library classes
-keep class com.squareup.picasso.** {*;}
-dontwarn com.squareup.picasso.**
# skip Moat classes
-keep class com.moat.** {*;}
-dontwarn com.moat.**

#IronSource
-keepclassmembers class com.ironsource.sdk.controller.IronSourceWebView$JSInterface {
    public *;
}
-keepclassmembers class * implements android.os.Parcelable {
    public static final android.os.Parcelable$Creator *;
}
-keep public class com.google.android.gms.ads.** {
   public *;
}
-keep class com.ironsource.adapters.** { *;
}

#Kiip
-keep public class me.kiip.**

#MoPub
# Keep public classes and methods.
-keepclassmembers class com.mopub.** { public *; }
-keep public class com.mopub.**
-keep public class android.webkit.JavascriptInterface {}

-keep class * extends com.mopub.mobileads.CustomEventBanner {}
-keepclassmembers class com.mopub.mobileads.CustomEventBannerAdapter {!private !public !protected *;}
-keep class * extends com.mopub.mobileads.CustomEventInterstitial {}
-keep class * extends com.mopub.mobileads.CustomEventNative {}

-keep class com.google.android.gms.common.GooglePlayServicesUtil {*;}
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient {*;}
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient$Info {*;}

-dontwarn com.mopub.**

#Tapjoy
-keep class com.tapjoy.** { *; }
-keep class com.moat.** { *; }
-keepattributes JavascriptInterface
-keepattributes *Annotation*
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents();
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL;
}
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
@com.google.android.gms.common.annotation.KeepName *;
}
-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;
}
-keep class com.google.android.gms.ads.identifier.** { *; }
-dontwarn com.tapjoy.**

#UnityAds
# Keep filenames and line numbers for stack traces
-keepattributes SourceFile,LineNumberTable

# Keep JavascriptInterface for WebView bridge
-keepattributes JavascriptInterface

# Sometimes keepattributes is not enough to keep annotations
-keep class android.webkit.JavascriptInterface {
   *;
}

# Keep all classes in Unity Ads package
-keep class com.unity3d.ads.** {
   *;
}

# Vungle
-dontwarn com.vungle.**
-dontnote com.vungle.**
-keep class com.vungle.** { *; }
-keep class javax.inject.*

# GreenRobot
-dontwarn de.greenrobot.event.util.**

# RxJava
-dontwarn rx.internal.util.unsafe.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
   long producerIndex;
   long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
   rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
   rx.internal.util.atomic.LinkedQueueNode consumerNode;
}
-keep class rx.schedulers.Schedulers { public static <methods>; }
-keep class rx.schedulers.ImmediateScheduler { public <methods>; }
-keep class rx.schedulers.TestScheduler { public <methods>; }
-keep class rx.schedulers.Schedulers { public static ** test(); }

# MOAT
-dontwarn com.moat.**
-keep class com.moat.** { public protected private *; }

# Retrofit
-dontwarn okio.**
-dontwarn retrofit2.Platform$Java8

# YouAppi
-keep class com.google.gson.**{ *;}
-keep class com.google.android.gms.**{*;}
-keep class com.youappi.sdk.**{*;}
-keep interface com.youappi.sdk.**{*;}
-keep enum com.youappi.sdk.**{*;}
-keepclassmembers class * {
   @android.webkit.JavascriptInterface <methods>;
}