Standalone SDK - Android

Appier Android SDK

We have 3 parts to integrate Appier Mobile SDK for Android

  • Integrating Appier Mobile SDK
  • ListView and RecyclerView
  • Advanced Usage

Current Support Ad Format

  • Native Ads
  • Banner Ads
  • Interstitial Ads
  • Video

1. Integrating Appier Mobile SDK

Step 1 - Prerequisites

  • Make sure your app's API level >= 18

Step 2 - Gradle Configuration

Please add jcenter to your repositories.

repositories {
    // ...
    mavenCentral()
}

dependencies {
    implementation 'com.appier:ads-android:2.0.0'
}

Step 3 - Manifest Configuration

To prevent your app from crashing, following are the recommended manifest configurations.

<manifest ...>
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

  <!--  Required for displaying floating window  -->
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
</manifest>

The following network security configuration is also required. Without this config, http traffics will be blocked in android 9 and higher.

<manifest ...>
  <application
    ...
    android:networkSecurityConfig="@xml/network_security_config"
  >
    ...
  </application>
</manifest>
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
  <base-config cleartextTrafficPermitted="true" />
</network-security-config>

Step 4 - GDPR Consent (Recommended)

In consent to GDPR, we strongly recommend to set the consent status to our SDK via Appier.setGDPRApplies() so that Appier Sdk does not track users' personal information. Without this configuration, Appier will NOT apply GDPR by default.
Note that this will impact the advertising performance hence impact the revenue.

import com.appier.ads.Appier;

public class MainActivity extends AppCompatActivity {
   @Override
   protected void onCreate(Bundle savedInstanceState) {
       // ...
       Appier.setGDPRApplies(true);
   }
}

Step 5 - Ad Format Integration

Overview

  • 5.1 - Native Ads
  • 5.2 - Banner Ads
  • 5.3 - Interstitial Ads
  • 5.4 - Video Ads

5.1 - Native Ads

Prepare Ad View
Native allows you to customize your own ad layout. You can either design yours or use the following sample.

Load Ad
To setup a native ad, you need to implement AppierNativeAd.EventListener and define zoneId. Then, use loadAd() to request ads. To show the loaded ad, you can access the rendered ad view via appierNativeAd.getAdView() and attach to wherever you want.

Destroy ad
Once you no longer use the ad, please destroy it to prevent memory leak.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/native_ad_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:textDirection="locale">

    <ImageView
        android:id="@+id/native_icon_image"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="10dp"
        android:layout_marginStart="10dp"
        android:layout_marginTop="10dp"
        android:background="@null"
        android:contentDescription="@null" />

    <TextView
        android:id="@+id/native_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="84dp"
        android:layout_marginStart="84dp"
        android:layout_marginTop="32dp"
        android:textColor="@android:color/darker_gray"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/native_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/native_icon_image"
        android:layout_marginLeft="10dp"
        android:layout_marginStart="10dp"
        android:layout_marginTop="10dp"
        android:textColor="@android:color/darker_gray" />

    <ImageView
        android:id="@+id/native_main_image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/native_text"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_marginStart="10dp"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:layout_marginEnd="10dp"
        android:layout_marginRight="10dp"
        android:adjustViewBounds="true"
        android:background="@null"
        android:contentDescription="native_main_image"
        android:minHeight="180dp"
        android:scaleType="centerCrop" />

    <Button
        android:id="@+id/native_cta"
        android:layout_width="wrap_content"
        android:layout_height="36dp"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/native_main_image"
        android:layout_marginEnd="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="10dp"
        android:clickable="true"
        android:focusable="true"
        android:text="Learn More"
        android:textStyle="bold" />

    <ImageView
        android:id="@+id/native_privacy_information_icon_image"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:contentDescription="Privacy Information Icon image"
        android:padding="10dp" />

</RelativeLayout>
AppierNativeAd appierNativeAd = new AppierNativeAd(someContext, new AppierAdUnitIdentifier("<your_ad_unit_id>"), new AppierNativeAd.EventListener() {
    @Override
    public void onAdLoaded(AppierNativeAd appierNativeAd) {
        Appier.log("[Sample App] onAdLoaded()");
        View adView = appierNativeAd.getAdView();
        LinearLayout adContainer = findViewById(R.id.ad_container);
        adContainer.addView(adView);
    }

    @Override
    public void onAdNoBid(AppierNativeAd appierNativeAd) {
        Appier.log("[Sample App] onAdNoBid()");
    }

    @Override
    public void onAdLoadFail(AppierError appierError, AppierNativeAd appierNativeAd) {
        Appier.log("[Sample App] onAdLoadFail()", appierError.toString());
    }

    @Override
    public void onAdShown(AppierNativeAd appierNativeAd) {
        Appier.log("[Sample App] onAdShown()");
    }

    @Override
    public void onImpressionRecorded(AppierNativeAd appierNativeAd) {
        Appier.log("[Sample App] onImpressionRecorded()");
    }

    @Override
    public void onImpressionRecordFail(AppierError appierError, AppierNativeAd appierNativeAd) {
        Appier.log("[Sample App] onImpressionRecordFail()", appierError.toString());
    }

    @Override
    public void onAdClick(AppierNativeAd appierNativeAd) {
        Appier.log("[Sample App] onAdClick()");
    }

    @Override
    public void onAdClickFail(AppierError appierError, AppierNativeAd appierNativeAd) {
        Appier.log("[Sample App] onAdClickFail()");
    }
});

appierNativeAd.setViewBinder(appierNativeViewBinder);
appierNativeAd.setZoneId("<your_zone_id>");
appierNativeAd.loadAd();
if (appierNativeAd != null) {
    appierNativeAd.destroy();
}

5.2 - Banner Ads

Load Ad
To setup a banner ad, you need to implement AppierBannerAd.EventListener and define zoneId. Then, use loadAd() to request ads. To show the loaded ad, you can access the rendered ad view via appierBannerAd.getView() and attach to wherever you want.

AppierBannerAd appierBannerAd = new AppierBannerAd(context, new AppierAdUnitIdentifier("<your_ad_unit_id>"), new AppierBannerAd.EventListener() {
    @Override
    public void onAdLoaded(AppierBannerAd appierBannerAd) {
        Appier.log("[Sample App]", "[Banner]", "onAdLoaded()");
        View adView = appierBannerAd.getView();
        LinearLayout adContainer = findViewById(R.id.ad_container);
        adContainer.addView(adView);
    }

    @Override
    public void onAdNoBid(AppierBannerAd appierBannerAd) {
        Appier.log("[Sample App]", "[Banner]", "onAdNoBid()");
    }

    @Override
    public void onAdLoadFail(AppierError appierError, AppierBannerAd appierBannerAd) {
        Appier.log("[Sample App]", "[Banner]", "onAdLoadFail()", appierError.toString());
    }

    @Override
    public void onViewClick(AppierBannerAd appierBannerAd) {
        Appier.log("[Sample App]", "[Banner]", "onViewClick()");
    }
});
appierBannerAd.setAdDimension(300, 250);
appierBannerAd.setZoneId("<your_zone_id>");
appierBannerAd.loadAd();

Shortcut
If you are not going to interact with banner's lifecycle, you can simply use AppierBannerView as an ad unit.

<com.appier.ads.AppierBannerView
    android:id="@+id/ad_container"
    android:layout_width="300dp"
    android:layout_height="250dp" />

Similar to above, you need to define AdDimension and zoneId. Then, use loadAd() to request ads. AppierBannerView will automatically show the ad once it is loaded.

AppierBannerView appierBannerView = findViewById(R.id.ad_container);
appierBannerView.setAdDimension(300, 250);
appierBannerView.setZoneId("<your_zone_id>");
appierBannerView.loadAd();

Destroy ad
Once you no longer use the ad, please destroy it to prevent memory leak. Use either one of following samples accordingly.

if (appierBannerAd != null) {
    appierBannerAd.destroy();
}
if (appierBannerView != null) {
    appierBannerView.destroy();
}

5.3 - Interstitial Ads

Load Ad
The minimal setup to prepare an interstitial requires to define AppierInterstitialAd.EventListener, AdDimension and zoneId. Then, use loadAd() to request ads.

Show Ad
Once the ad is loaded, you can use showAd() to display it. Before showing the ad, we suggest you to verify whether the ad is available via isLoaded(). If interstitial is not ready when you call showAd(), there will be no-ops.

Destroy Ad
Once you no longer use the ad, please destroy it to prevent memory leak.

AppierInterstitialAd appierInterstitialAd = new AppierInterstitialAd(this, new AppierAdUnitIdentifier("<your_ad_unit_id>"), new AppierInterstitialAd.EventListener() {
    @Override
    public void onAdLoaded(AppierInterstitialAd appierInterstitialAd) {
        Appier.log("[Sample App]", "Interstitial loaded");
    }

    @Override
    public void onAdNoBid(AppierInterstitialAd appierInterstitialAd) {
        Appier.log("[Sample App]", "Interstitial ad returns no bid");
    }

    @Override
    public void onAdLoadFail(AppierError appierError, AppierInterstitialAd appierInterstitialAd) {
        Appier.log("[Sample App]", "Interstitial load failed");
    }

    @Override
    public void onShown(AppierInterstitialAd appierInterstitialAd) {
        Appier.log("[Sample App]", "Interstitial shown");
    }

    @Override
    public void onShowFail(AppierError appierError, AppierInterstitialAd appierInterstitialAd) {
        Appier.log("[Sample App]", "Interstitial show failed with error: " + appierError);
    }

    @Override
    public void onDismiss(AppierInterstitialAd appierInterstitialAd) {
        Appier.log("[Sample App]", "Interstitial dismissed");
      
      	// You can destroy Interstitial here to prevent from memory leak
        interstitialAd.destroy();
    }
});

appierInterstitialAd.setAdDimension(300, 250);
appierInterstitialAd.setZoneId("<your_zone_id>");
appierInterstitialAd.loadAd();
if (appierInterstitialAd.isLoaded()) {
    appierInterstitialAd.showAd();
}
if (appierInterstitialAd != null) {
    appierInterstitialAd.destroy();
}

5.4 - Video Ads

Load Ad
The minimal setup to prepare a video requires to define VideoAd.EventListener, zoneId. Then, use loadAd() to request ads.

Show Ad
Once the ad is loaded, you can showAd() to display it. Before showing the ad, we suggest you to verify whether the ad is available via isLoaded(). If video is not ready when you call showAd(), there will be no-ops.

Destroy Ad
Once you no longer use the ad, please destroy it to prevent memory leak.

Advanced Usage
You can use setOrientation() to set video ad orientation before loadAd(), or the ad orientation would be the screen orientation when you called loadAd()

import com.appier.ads.VideoAd;

// ...

VideoAd videoAd = new VideoAd(this, new AppierAdUnitIdentifier("<your_ad_unit_id>"), new VideoAd.EventListener() {
		@Override
    public void onAdLoaded(VideoAd videoAd) {
      	Appier.log("[Sample App]", "Video loaded");
    }
  
  	@Override
    public void onAdNoBid(VideoAd videoAd) {
        Appier.log("[Sample App]", "Video ad returns no bid");
    }
  
  	@Override
  	public void onAdLoadFail(AppierError appierError, VideoAd videoAd) {
        Appier.log("[Sample App]", "Video load failed");
    }
  
    @Override
    public void onViewClick(VideoAd videoAd) {
        Appier.log("[Sample App]", "Video clicked");
    }
  
    @Override
    public void onViewClickFail(AppierError appierError, VideoAd videoAd) {
        Appier.log("[Sample App]", "Video click failed");
    }
  
    @Override
    public void onShown(VideoAd videoAd) {
        Appier.log("[Sample App]", "Video shown");
    }

    @Override
    public void onAdVideoComplete(VideoAd videoAd) {
        Appier.log("[Sample App]", "Video complete");
    }

    @Override
    public void onShowFail(AppierError appierError, VideoAd videoAd) {
        Appier.log("[Sample App]", "Video show failed with error: " + appierError);
    }

    @Override
    public void onDismiss(VideoAd videoAd) {
        Appier.log("[Sample App]", "Video dismissed");

        // You can destroy video here to prevent from memory leak
        videoAd.destroy();
    }
});

videoAd.setZoneId("<your_zone_id>");
videoAd.loadAd();
if (videoAd.isLoaded()) {
  	videoAd.showAd();
}
if (videoAd != null) {
  	videoAd.destroy();
}
videoAd.setZoneId("<your_zone_id>");

// Set Appier video ad orientation
videoAd.setOrientation(Configuration.ORIENTATION_PORTRAIT);
// or videoAd.setOrientation(Configuration.ORIENTATION_LANDSCAPE);

videoAd.loadAd();

2. ListView and RecyclerView

Appier SDK supports to insert native or banner into ListView or RecyclerView. You will need to wrap your own original adapter within AppierAdAdapter or AppierRecyclerAdapter. Then use wrappedAdapter.insertAd() to control the insertion.

ListView

Prepare a ListView in your layout.

<ListView
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:drawSelectorOnTop="false" />

Then, wrap the original adapter within AppierAdAdapter and set to list view.

ArrayAdapter<...> adapter = new ArrayAdapter(...);
ListView listView = findViewById(R.id.list);
AppierAdAdapter appierAdAdapter = new AppierAdAdapter(adapter);
listView.setAdapter(appierAdAdapter);

Create a normal native (or banner), and choose an insertPosition to insert when the ad is loaded.

AppierNativeAd appierNativeAd = new AppierNativeAd(someContext, new AppierAdUnitIdentifier("<your_ad_unit_id>"), new AppierNativeAd.EventListener() {
    @Override
    public void onAdLoaded(AppierNativeAd appierNativeAd) {
        try {
            appierAdAdapter.insertAd(insertPosition, appierNativeAd);
        } catch (Exception e) {
            Appier.log("[Sample App] Fail to insert ad into list. Maybe the position is out of bound or is already used.");
        }
    }

    // ...
});

RecyclerView

Prepare a RecyclerView in your layout.

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recycler"
    android:scrollbars="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Then, wrap the original adapter within AppierRecyclerAdapter and set to recycler view.

MyRecyclerViewAdapter adapter = new MyRecyclerViewAdapter(...);
RecyclerView recyclerView = findViewById(R.id.recycler);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
AppierRecyclerAdapter appierRecyclerAdapter = new AppierRecyclerAdapter(adapter);
recyclerView.setAdapter(appierRecyclerAdapter);

Create a normal banner (or native), and choose an insertPosition to insert when the ad is loaded.

AppierBannerAd appierBannerAd = new AppierBannerAd(this, new AppierAdUnitIdentifier("<your_ad_unit_id>"), new AppierBannerAd.EventListener() {
    @Override
    public void onAdLoaded(AppierBannerAd appierBannerAd) {
        try {
            appierRecyclerAdapter.insertAd(insertPosition, appierBannerAd);
        } catch (Exception e) {
            Appier.log("[Sample App] Fail to insert ad into list. Maybe the position is out of bound or is already used.");
        }
    }

    // ...
});

3. Advanced Usage

Enable Testing Mode

To make developers test the SDK integration easily, you can enable test mode globally via Appier.setTestMode. In test mode, Appier SDK by default will force bid. You can also set to different Appier.TestMode to ensure SDK's behavior.

Appier.setTestMode(true);  // Same as Appier.TestMode.BID
Appier.setTestMode(false); // Same as Appier.TestMode.FALSE
Appier.setTestMode(Appier.TestMode.FALSE);
Appier.setTestMode(Appier.TestMode.BID);
Appier.setTestMode(Appier.TestMode.NO_BID);

Set Targeting

For all ad formats, you can optionally set targeting via following methods:

  • setYob()
  • setGender()
  • addKeyword()
// Banner
appierBannerView.setYob(2001);
appierBannerView.setGender(AppierTargeting.Gender.FEMALE);
appierBannerView.addKeyword("interest", "sports");

// Interstitial
appierInterstitialAd.setYob(2001);
appierInterstitialAd.setGender(AppierTargeting.Gender.MALE);
appierInterstitialAd.addKeyword("interest", "sports");

// Native
mAppierNativeAd.setYob(2001);
mAppierNativeAd.setGender(AppierTargeting.Gender.OTHER);
mAppierNativeAd.addKeyword("interest", "sports");