Android SDK Native Ads Video

357 views 2019-07-18 Ofer Garnett 0

Getting Started

Latest Android Native Video version: 2.0.0
Release date: 23-Jun 2019

This document details the process of integrating YouAppi SDK Native Ads Video to your Android app.

If you have any questions, please, feel free to email us: [email protected]

The basic steps of integration are:

  • Add our SDK AAR or Gradle dependency to your project.
  • Create a custom view of your native video unit.
  • Load native video.
  • Bind and show native video.

Requirements:

Minimum API level: 14, Android 4.0

Please, note that SDK can access some of user’s private information, so, make sure you have read this part carefully. 

Integration

Integrate using AAR file

Our latest SDK version can be downloaded as a ZIP file from the following URL:

YouAppi Android SDK Native Ads Video

The ZIP file contains:

  • Static SDK AAR file – youappi-sdk-android-nativeads-static.aar.
  • Video SDK AAR file – youappi-sdk-android-nativeads-video.aar.

The static aar is used for showing native ad banners. The video aar is used for showing native ad videos and banners.

Copy both files to the apps\libs folder of your project. Add the following to the project build.gradle file inside the repositories section:

repositories {
    flatDir {
        dirs 'libs'
    }
}

Please note that you need to add to your app build.gradle file the following under dependencies section:

dependencies {
    xoplayer
}

If Manifest Merger is disabled and your app is running on older devices, the following permissions should be added to the AndroidManifest.xml:

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

Integrate using repository

  • Add the following to the project build.gradle file inside the repositories section:
    maven { url "http://repository.youappi.com/repository/release" }
    
  • Add to your app build.gradle file the following under dependencies section:
    dependencies {
         implementation "com.youappi.sdk:youappi-sdk-android-nativeads-video:2.0.0"
    }

Using the SDK

Custom Layout

  • Create your custom native ad view using Android layout XML file.
  • The root element of the custom view should be of type: com.youappi.sdk.nativeads.views.NativeAdView
  • The custom native ad view contains the following controls.
ControlDefault IDMandatory
Icon (ImageView)nativead_iconYes (could be used with/without or instead of Image)
Title (TextView)nativead_titleYes
Description (TextView)nativead_descriptionNo
Image-Media (MediaView)nativead_mediaYes (could be used with/without or instead of Icon)
Call to action-CTA (Button)nativead_ctaYes
Rating (TextView)nativead_ratingNo
Rating Icon (ImageView)nativead_rating_iconNo
Opt out (ImageView)nativead_optYes

All mandatory controls should be used as an exception will be thrown if one of the mandatory controls is missing. Please, note that you may use or Icon, or Image, or both of them depending on your needs. Each control has a default ID. Using default IDs will save you from later binding controls with their matching ids.

Here is an example of a custom layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nativead_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/darker_gray">

    <LinearLayout
        android:id="@+id/na_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="20dp"
        android:layout_marginRight="10dp"
        android:layout_marginBottom="20dp"
        android:background="@android:color/white"
        android:orientation="vertical"
        android:padding="10dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="left"
            android:orientation="horizontal"
            tools:ignore="RtlHardcoded">

            <ImageView
                android:id="@id/nativead_icon"
                android:layout_width="60dp"
                android:layout_height="60dp"
                android:layout_marginBottom="10dp"
                android:tag="na_icon"
                tools:ignore="ContentDescription,RtlHardcoded"
                tools:src="@drawable/ic_launcher_foreground" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:orientation="vertical"
                tools:ignore="RtlHardcoded">

                <TextView
                    android:id="@id/nativead_title"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="15dp"
                    android:ellipsize="end"
                    android:gravity="left"
                    android:lines="1"
                    android:tag="na_title"
                    android:textColor="#000000"
                    android:textSize="16sp"
                    tools:text="title" />

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="left|bottom"
                    android:orientation="horizontal"
                    tools:ignore="UseCompoundDrawables">

                    <ImageView
                        android:id="@id/nativead_rating_icon"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginRight="2dp"
                        android:src="@drawable/youappi_ads_star"
                        tools:ignore="ContentDescription" />

                    <TextView
                        android:id="@id/nativead_rating"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textColor="#000000"
                        android:textSize="16sp"
                        tools:text="fdfds" />

                </LinearLayout>

                <TextView
                    android:id="@id/nativead_description"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="4dp"
                    android:ellipsize="end"
                    android:textColor="#000000"
                    tools:text="TextView" />

            </LinearLayout>

        </LinearLayout>

        <com.youappi.sdk.nativeads.video.MediaView
            android:id="@id/nativead_media"
            android:layout_width="match_parent"
            android:layout_height="200dp">

            <ImageView
                android:id="@+id/nativead_opt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:layout_alignParentLeft="true"
                android:layout_marginTop="2dp"
                android:layout_marginLeft="2dp"/>

        </com.youappi.sdk.nativeads.video.MediaView>

        <Button
            android:id="@id/nativead_cta"
            android:layout_width="104dp"
            android:layout_height="40dp"
            android:layout_gravity="right"
            android:tag="na_action"
            android:text="install"
            android:textColor="#ffffff"
            tools:ignore="HardcodedText,RtlHardcoded" />

    </LinearLayout>

    <ImageView
        android:id="@id/nativead_opt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginTop="28dp"
        android:layout_marginRight="18dp"
        android:textColor="#aa000000"
        tools:ignore="ContentDescription,HardcodedText,RtlHardcoded" />

</RelativeLayout>

Here is how this video layout should look after it is downloaded and rendered:

Loading and showing native video

  • Loading a native ad is done by creating an instance of VideoNativeAdLoader.
  • The following parameter should be supplied in order to create an instance of a native ad loader:
    • Context.
    • Access token.
    • Ad unit id.
  • Please note: YouAppi ad unit id is created and controlled by the app developer. An ad unit id later appears in reports and helps to analyse performance of each ad unit. An ad unit id should contain only letters (lowercase or uppercase), numbers and underscores.
  • Once an instance of a video native ad loader is created it can be assigned with the following properties:
    • User consent.
    • Age restricted user.
    • Ad response listener – contains onNativeAdResponse callback that is called once a native ad is successfully loaded.
    • Native ad listener – contains the following callbacks:
      • onFailure – Called when fails loading a native ad.
      • onAdClicked – Called when a native ad was clicked.
      • onImpression – Called when an impression is fired. Impression is fired after a native ad was shown for more than one second on more than 50% of the screen.

Here is an example of how a code looks:

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

    View advView;
    View advView2;
    View advView3;
    NativeVideoAdsRenderer nativeVideoAdsRenderer;
    int counter = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        advView = findViewById(R.id.adv_view);
        advView2 = findViewById(R.id.adv_view2);
        advView3 = findViewById(R.id.adv_view3);

        Button envButton = findViewById(R.id.env);
        if (BuildConfig.DEBUG) {
            envButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    EnvironmentChanger.openEnvironment(MainActivity.this);
                }
            });
        } else {
            envButton.setVisibility(View.GONE);
        }

        final Button buttonLoadAd = findViewById(R.id.buttonLoadAd);

        buttonLoadAd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                loadAd();
            }
        });

        VideoViewMapper.Builder builder = new VideoViewMapper.Builder(R.layout.native_ad_layout);
        builder.setTitleViewId(R.id.nativead_title)
                .setMediaViewId(R.id.nativead_media)
                .setIconViewId(R.id.nativead_icon)
                .setCtaViewId(R.id.nativead_cta)
                .setDescriptionViewId(R.id.nativead_description)
                .setRatingViewId(R.id.nativead_rating)
                .setRatingIconViewId(R.id.nativead_rating_icon);
        nativeVideoAdsRenderer = new NativeVideoAdsRenderer(builder.build());

    }

    private void loadAd() {
        VideoNativeAdLoader videoNativeAdLoader = new VideoNativeAdLoader.Builder(MainActivity.this,
                "821cfa77-3127-42b5-9e6b-0afcecf77c67",
                "nativeAdTest")
                .setNativeAdResponseListener(new NativeAdResponseListener() {
                    @Override
                    public void onNativeAdResponse(NativeAd videoNativeAd) {
                        int reminder = counter % 3;
                        switch (reminder) {
                            case 0:
                                nativeVideoAdsRenderer.renderAd(advView, (VideoNativeAd) videoNativeAd);
                                break;
                            case 1:
                                nativeVideoAdsRenderer.renderAd(advView2, (VideoNativeAd) videoNativeAd);
                                break;
                            case 2:
                                nativeVideoAdsRenderer.renderAd(advView3, (VideoNativeAd) videoNativeAd);
                                break;
                        }

                        counter++;
                    }
                })
                .setCreativeType(NativeTypes.CreativeType.Video)
                .setVolumeMode(NativeTypes.VolumeMode.Mute)
                .setNativeAdListener(new NativeAdListener() {
                    @Override
                    public void onFailure(NativeTypes.ErrorCode errorCode, Exception e) {
                        Log.e(TAG, "ad failiure. code: " + errorCode.name() + " exception: " + e.getMessage());
                    }

                    @Override
                    public void onAdClicked() {
                        Log.e(TAG, "ad clicked");
                    }

                    @Override
                    public void onAdImpression() {
                        Log.e(TAG, "Impression");
                    }
                })
                .build();

        AdRequest adRequest = new AdRequest.Builder()
                .addCustomParam("user_id", "1234")
                .setAge(35)
                .setGender(AdRequest.Gender.Male)
                .build();

        videoNativeAdLoader.load(adRequest);
    }

Please note that you have an option to mute the volume at the start of a native video using the setVolumeMode method shown above.

GDPR User’s Consent

The userConsent flag value should be determined by the app developer according to the User’s response to a Consent Request and according to the user being subject to the GDPR rules (e.g.: an EU residence). The userConsent flag value signals to YouAppi the permission to process and store the user’s Personal Information (e.g.: Advertising ID and IP address). In case that the flag value is false, YouAppi may decide not to respond to the ad request, since the user cannot be detected and his actions cannot be attributed to the user and hence also to YouAppi and to the app developer. By default user consent it set to true.

GDPR user consent is set by:

videonativeAdLoader.setUserConsent(userConsent)
  • If the user is known to be in an age restricted class (e.g.: under the age of 16 in some countries or under the age of 13 in other countries ) then the age restricted indication should be passed:
videonativeAdLoader.setAgeRestrictedUser(ageRestricted);

Logging and troubleshooting

You can log SDK errors by implementing onFailure callback. For example:

videonativeAdLoader.setNativeAdListener(new NativeAdListener() {
                            @Override
                            public void onFailure(ErrorCode errorCode, Exception e) {
                                Log.e(TAG, "Failed in native request: " + errorCode, e);
                            }

                            @Override
                            public void onAdClicked() {
                            }

                            @Override
                            public void onAdImpression() {
                            }
                        })

Load and Show best practices

  • Make sure to load the ad about 30 seconds before you want to show it since it takes time for the ad and assets to be prepared.
  • Make sure to show an ad as close as possible to its load, in order to have a better fill rate and relevant ads.
  • Make sure not to wait too long before showing an ad, since the ad will be expired 5 hours after being called for. In other words, “show” must be performed no more than 5 hours after the “load”.
  • Loading an ad too many times without showing it might cause YouAppi servers to block the SDK from requests.

Demo App

A demo app showing a simple usage of the SDK can be found in the following Github repository:

https://github.com/YouAppi/youappi-sdk-android-demo

The demo app is in the module: app-demo-nativevideo

Please make sure to read the README.md file for further instructions.