Integration guide - adcharge/sdk-android-demo GitHub Wiki

Overview

Integrated AdCharge SDK provides possibility to show ads upon incoming call event or/and in the application directly. With active ads upon incoming call User will see small banner, which is a preview of a large one. User can interact with the small banner by closing it or sliding it up and down. After call has finished User will see large, full-screen banner. User is able to interact, within 10 seconds with it by closing, hiding or clicking on it. After 10 seconds, if no action was done, banner will be automatically closed. If banner was clicked User will be redirected to default mobile device browser for further actions. Active in application ads option gives possibility to show full screen banner directly in application in a flexible way and open application browser in case of a click (if such exists in the applications).

Preconditions, requirements

For integration with AdCharge SDK you will need:

  • 2 .aar files
  • server base URL (will be provided by AdCharge manager)
  • individual key of traffic source (will be provided by AdCharge manager)
  • your application

2 .aar files

  • provided by AdCharge, ask your AdCharge manager

Server base URL

  • provided by AdCharge, ask your AdCharge manager

Individual key of traffic source

  • provided by AdCharge, ask your AdCharge manager

Application requirements

  • application must have minimum API level 19 or above (Android 4.4 KitKat) – <app_root_directory>/app/build.gradle minSdkVersion
  • application must be ready to request user about next permissions: – display over other apps – manage phone calls – access device location

Integration

Dependencies

  • add aar files to your project as shown in [https://developer.android.com/studio/projects/android-library.html#AddDependency]

  • add dependencies in your <app_root_directory>/app/build.gradle

dependencies {
    //.....yours project dependencies

    // >>> start of AdCharge dependencies
    // dependencies for AdCharge API wrapper
    implementation project(':adcharge_api_sdk-release')
    implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.8.1'
    implementation group: 'com.squareup.okhttp3', name: 'logging-interceptor', version: '3.10.0'
    implementation "com.squareup.okhttp3:okhttp-urlconnection:3.0.0-RC1"
    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.7.5'

    // dependencies for AdCharge SDK
    implementation project(":adcharge_sdk-release")
    implementation 'com.google.android.gms:play-services-location:11.0.4'
    implementation 'com.android.support:appcompat-v7:27.1.1'
    // <<< end of AdCharge dependencies
}
  • make sure adcharge_api_sdk-release and adcharge_sdk-release are named same to .aar files in lines
implementation project(':adcharge_api_sdk-release')
implementation project(":adcharge_sdk-release")

Compatibility config

  • add dependencies in your <app_root_directory>/app/build.gradle
android {
//.....yours project configs
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

Fast Start Code

  • pick an action in your app, which will initialize AdCharge. For example, switcher

xml:

<Switch
            android:id="@+id/use_adcharge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Show me advertisement" />

java:

protected void onCreate(Bundle savedInstanceState) {
        .....
        Switch useAdcharge = findViewById(R.id.use_adcharge);
        .....
    }
  • create new class to place there integration code

java:

        import android.app.Activity;
        import android.content.Context;
        import android.os.AsyncTask;
        import android.provider.Settings;
        import android.widget.CompoundButton;

        import java.io.IOException;
        import java.net.MalformedURLException;
        import java.util.ArrayList;
        import java.util.List;
        
        import eu.adcharge.api.ApiException;
        import eu.adcharge.api.ApiValidationException;
        import eu.adcharge.api.entities.User;
        import eu.adcharge.sdk.logic.AdCharge;
        
        class AdChargeDependentCode {
            private static final String URL = "https://adm.adcharge.eu/api/"; // Server base URL
            private static final AdCharge.Settings SETTINGS = new AdCharge.Settings(); // default settings
            private static final String TRAFFIC_SOURCE_KEY = "Speedflow-AdCharge";  // Individual key of traffic source
        
            private static List<String> getAdchargeCredentailsForUniqueUser(Context ctx) {
                List<String> credentials = new ArrayList<>();
                String androidId = Settings.Secure.getString(ctx.getContentResolver(), Settings.Secure.ANDROID_ID);
                credentials.add(androidId);
                credentials.add("verySecureUserPassword");
                return credentials;
            }
        
            static CompoundButton.OnCheckedChangeListener LISTENER;
        
            static AdCharge initAdcharge(final Activity activity) throws MalformedURLException {
        
                final AdCharge adCharge = new AdCharge(URL, activity, SETTINGS);
                LISTENER = new CompoundButton.OnCheckedChangeListener() {
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        if (isChecked) {
                            List<String> credentials = getAdchargeCredentailsForUniqueUser(activity);
                            final String username = credentials.get(0);
                            final String password = credentials.get(1);
                            new LoginUserTask(username, password, activity, adCharge).execute();
                        } else {
                            new LogoutUserTask(adCharge).execute();
        
                        }
                    }
                };
                return adCharge;
            }
        
            static class LoginUserTask extends AsyncTask<Object, Object, Object> {
                private String username;
                private String password;
                private Activity activity;
                private AdCharge adCharge;
        
                LoginUserTask(String username, String password, Activity activity, AdCharge adCharge) {
                    this.username = username;
                    this.password = password;
                    this.activity = activity;
                    this.adCharge = adCharge;
                }
        
                @Override
                protected Object doInBackground(Object[] objects) {
                    try {
                        adCharge.login(username, password, TRAFFIC_SOURCE_KEY, activity);
                    } catch (ApiException | IOException | ApiValidationException e) {
                        User toBeRegistered = new User();
                        toBeRegistered.setUsername(username);
                        toBeRegistered.setPassword(password);
                        try {
                            adCharge.registerSubscriberUser(toBeRegistered, TRAFFIC_SOURCE_KEY);
                            adCharge.login(username, password, TRAFFIC_SOURCE_KEY, activity);
                        } catch (ApiException | IOException | ApiValidationException e1) {
                            e1.printStackTrace();
                        }
                    }
                    return null;
                }
            }
        
            static class LogoutUserTask extends AsyncTask<Object, Object, Object> {
                private AdCharge adCharge;
        
                LogoutUserTask(AdCharge adCharge) {
                    this.adCharge = adCharge;
                }
        
                @Override
                protected Object doInBackground(Object[] objects) {
                    adCharge.logout();
                    return null;
                }
            }
        }
  • connect your switcher to AdCharge java:
        Switch useAdcharge = findViewById(R.id.use_adcharge);
        try {
            AdCharge adcharge = AdChargeDependentCode.initAdcharge(this);
            useAdcharge.setOnCheckedChangeListener(AdChargeDependentCode.LISTENER);
            useAdcharge.setChecked(adcharge.isLoggedIn());
        } catch (MalformedURLException ignored) {
            useAdcharge.setEnabled(false);
        }

Now if your switcher is on you should see advertisement upon incoming call

Full-screen in-app ads

  • add in AdChargeDependentCode AsyncTaskWithTimeout class

    java:

        class AdChargeDependentCode {
            ...
            abstract static class AsyncTaskWithTimeout<Params, Progress, Result>
                    extends AsyncTask<Params, Progress, Result> {
                private final long timeout;
                private final TimeUnit units;
                private final Activity context;

                // used for interruption
                private Thread backgroundThread;

                public AsyncTaskWithTimeout(Activity context, long timeout, TimeUnit units) {
                    this.context = context;
                    this.timeout = timeout;
                    this.units = units;
                }

                @Override
                protected final void onPreExecute() {
                    Thread timeoutThread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                // start the timeout ticker
                                AsyncTaskWithTimeout.this.get(timeout, units);
                            } catch (InterruptedException e) {
                                Thread.currentThread().interrupt();
                            } catch (ExecutionException e) {
                                onException(e);
                            } catch (TimeoutException e) {
                                AsyncTaskWithTimeout.this.interruptTask();
                                context.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        onTimeout();
                                    }
                                });

                            }
                        }
                    });
                    timeoutThread.setDaemon(true);
                    onPreExec();
                    timeoutThread.start();
                }
                
                protected void onPreExec() {
                }

                @Override
                protected final Result doInBackground(Params... params) {
                    // save off reference to background thread so it can be interrupted on timeout
                    this.backgroundThread = Thread.currentThread();
                    return runInBackground(params);
                }
                
                protected abstract Result runInBackground(Params... params);

                protected void onTimeout() {
                }

                protected void onException(ExecutionException e) {
                    throw new RuntimeException(e);
                }

                private final void interruptTask() {
                    if (backgroundThread != null) {
                        backgroundThread.interrupt();
                    }
                }
            }
        }
  • create new activity for full-screen in-app advertisement

    By using AsyncTaskWithTimeout it's possible to limit show ad operation with specific timeframe (1 second or less recommended if ad was preloaded beforehand. See next paragraph about preloading ad)

    java:

        import android.content.Intent;
        import android.os.Bundle;
        import android.view.View;
        import android.widget.ImageView;

        import android.support.v7.app.AppCompatActivity;

        import java.io.IOException;
        import java.util.concurrent.TimeUnit;

        import eu.adcharge.api.ApiException;
        import eu.adcharge.api.ApiValidationException;
        import eu.adcharge.api.NoAdvertisementFoundException;
        import eu.adcharge.sdk.logic.AdCharge;
        import eu.adcharge.sdk.logic.InAppAdvertisement;

        public class AdActivity extends AppCompatActivity {

            private boolean shown = false;

            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                final AdCharge adCharge = ((Application) getApplication()).getAdCharge();
                new AdChargeDependentCode.AsyncTaskWithTimeout<Void, Void, InAppAdvertisement>(this, 1, TimeUnit.SECONDS) {
                    @Override
                    protected InAppAdvertisement runInBackground(Void... objects) {
                        try {
                            return adCharge.getInAppAdvertisement();
                        } catch (NoAdvertisementFoundException e) {
                            // or just no ads for this user available (normal flow)
                            // or, if ad was preloaded long time ago - it's already invalidated and new one isn't available
                            // (there are different reasons for invalidation, and better not to show this ad at all)
                        } catch (ApiException | ApiValidationException | IOException e) {
                            e.printStackTrace();
                            // might be a bug or temporal network issue
                            // make sense to log and collect data, such cases, if shared, might help us
                        }
                        return null;
                    }

                    @Override
                    protected void onPostExecute(final InAppAdvertisement ad) {
                        if (ad == null)
                            finish(); // Something went wrong (ad has expired, or wasn't preloaded and no new ads are available)
                        shown = true;
                        ImageView adSpace = findViewById(R.id.banner);
                        ad.onDisplayed(); // Responsible for impression report. Mandatory
                        adSpace.setImageBitmap(ad.getBanner());
                        adSpace.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                Intent browserIntent = new Intent(Intent.ACTION_VIEW, ad.getTrackingUri());
                                browserIntent.putExtra("android.support.customtabs.extra.SESSION", getPackageName());
                                browserIntent.putExtra("android.support.customtabs.extra.EXTRA_ENABLE_INSTANT_APPS", true);
                                startActivity(browserIntent);
                            }
                        });
                    }

                    @Override
                    protected void onTimeout() {
                        finish(); // In case of any issue for set timeout - operation took too long (1 second by default)
                    }
                }.execute();
                setContentView(R.layout.activity_ad);
            }

            @Override
            protected void onResume() {
                super.onResume();
                if (shown) finish();
            }
        }

xml:

        <?xml version="1.0" encoding="utf-8"?>
        <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".AdActivity">
            <ImageView
                android:id="@+id/banner"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="fitCenter" />
        </android.support.constraint.ConstraintLayout>
  • preload of in-app ads

    If it's possible to predict moment, when ad supposed to be shown - preload it few seconds before usage, but no more, than 30 seconds, because that exact ad may become obsolete for different reasons with time.

    Preload is not required, but improves performance and gives warranty for app there's an advertisement for user.

    Preload is recommended , on 'get ad for direct usage'. SDK checks if there's preloaded ad and is it still valid, if not - attempt to get another ad from net will be in place.

    By using AsyncTaskWithTimeout it's possible to limit operation in timeframe (5 seconds should be more, than enough, if ad is not loaded in 5 seconds, there's definitely some issues with connection or any other sort of, no point to continue, regular time is ~0.5 or less, depends on connection quality).

    java:

        new AdChargeDependentCode.AsyncTaskWithTimeout<Void, Void, Void>(MainActivity.this, 5, TimeUnit.SECONDS) {
            boolean adPreloaded = false;
            @Override
            protected Void runInBackground(Void... voids) {
                try {
                    adCharge.preloadInAppAdvertisement();
                    adPreloaded = true;
                } catch (NoAdvertisementFoundException e) {
                    // just no advertisement for this user available
                    // (normal flow, happens for different reasons)
                } catch (ApiException | ApiValidationException | IOException e) {
                    e.printStackTrace();
                    // might be a bug or temporal network issue
                    // make sense to log and collect data, such cases, if shared might help AdCharge to improve it
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void aVoid) {
                if (adPreloaded) {
                    Intent adActivity = new Intent(getApplicationContext(), AdActivity.class);
                    adActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    startActivity(adActivity);
                }
            }
        }.execute();

Troubleshooting. What to do if no ads display after integration

  • Check if Advertiser exists.
  • Check if Advertiser has money on his account. If not contact AdCharge.
  • Check if Creative is uploaded
  • Check if Campaign is created
  • Check if Campaign is verified by Admin
  • Check if Campaign is verified by Operator
  • Check if created Campaign is supported by Operator
  • Check if Campaign start date is not in future
  • Check if Campaign is still active
  • Check if daily or/and total budget of the Campaign has not exceeded
  • Check if User corresponds to audience requirement
  • Check if targeted Country of the Campaign corresponds to User location

User data

After successfully created instance of AdCharge class and simple test passed you might need to extend and provide more info about your user, what includes:

  • Registration of subscriber
  • Verification of subscriber
  • Get subscriber profile
  • Update profile of subscriber

Registration of subscriber

In the code currently you have Android device ID used as username and password - just hardcoded string. You will need to provide unique username which might be a hashed version of username in your application and generated password. Also, by providing information of user's birthday and gender more precise targeting of advertisement сan be used and more variety of ads can be shown. As a result you will have unverified account, which needs to be confirmed later.

import eu.adcharge.api.entities.User;
import eu.adcharge.api.entities.Gender;
import eu.adcharge.sdk.logic.AdCharge;

static class RegisterUserTask extends AsyncTask {
        private AdCharge adCharge;

        RegisterUserTask(AdCharge adCharge) {
            this.adCharge = adCharge;
        }

        @Override
        protected Object doInBackground(Object[] objects) {
            String username = "username";// To be provide unique username connected to this exact user of your app
            String password = "password";// To be provide generated password
            Date birthday = null;
            Gender gender = Gender.UNDEFINED;// or Gender.MALE, or Gender.FEMALE
            try {
                User toBeRegistered = new User();
                toBeRegistered.setUsername(username);
                toBeRegistered.setPassword(password);
                User notVerifiedUser = adCharge.registerSubscriberUser(toBeRegistered, TRAFFIC_SOURCE_KEY);
            } catch (ApiException | IOException | ApiValidationException e) {
                // do nothing
            }
            return null;
        }
    }

Verification of subscriber

Upon registration subscriber will be checked by sending unique secret code to trusted service (your API) That service can be configured to deliver or not confirmation code for every exact registration request. It could be automated registration (no code needed) You will need to find a way using secured channel to get this code from your API With this code registration of the user can be confirmed.

import eu.adcharge.sdk.logic.AdCharge;

static class ConfirmUserTask extends AsyncTask {
    private AdCharge adCharge;
    private String confirmationCode;

    ConfirmUserTask(AdCharge adCharge, String confirmationCode) {
        this.adCharge = adCharge;
        this.confirmationCode = confirmationCode;
    }

    @Override
    protected Object doInBackground(Object[] objects) {
        try {
            adCharge.confirmUser(confirmationCode);
        } catch (ApiException | IOException | ApiValidationException e) {
            // do nothing
        }
        return null;
    }
}

Then you may login as described in

Get subscriber profile

If you need to get information about logged in subscriber

import eu.adcharge.api.entities.User;
import eu.adcharge.sdk.logic.AdCharge;

static class GetUserInfoTask extends AsyncTask {
        private AdCharge adCharge;

        GetUserInfoTask(AdCharge adCharge) {
            this.adCharge = adCharge;
        }

        @Override
        protected Object doInBackground(Object[] objects) {
            try {
                User user =  adCharge.getApiWrapper().getUserInfo();               
            } catch (ApiException | IOException | ApiValidationException e) {
                // do nothing
            }
            return null;
        }
    }

User class contains

  • int id;
  • String username;
  • String operator_name;
  • Date birthday;
  • Gender gender;
  • Date date_joined;
  • List interests;

Updating profile of subscriber

For any case, if you need to update information about subscriber

import eu.adcharge.api.entities.User;
import eu.adcharge.api.entities.Gender;
import eu.adcharge.api.entities.Interest;
import eu.adcharge.sdk.logic.AdCharge;

static class UpdateUserInfoTask extends AsyncTask {
    private AdCharge adCharge;
    private User user;

    UpdateUserInfoTask(AdCharge adCharge, User user) {
        this.adCharge = adCharge;
        this.user = user;
    }

    @Override
    protected Object doInBackground(Object[] objects) {
        try {
            // here how you can get List of supported interests
            List<Interest> availableInterests = adCharge.getApiWrapper().getAvailableInterests();
            for(Interest interest : availableInterests){
                if(<user interested in>){
                 user.getInterests().add(interest);
                }
            }
            user.setBirthday(null);
            user.setGender(Gender.UNDEFINED);// or Gender.MALE or Gender.FEMALE
            user.setPassword("NEW_PASSWORD");
            adCharge.getApiWrapper().saveUser(user); // save user profile
        } catch (ApiException | IOException | ApiValidationException e) {
            // do nothing
        }
        return null;
    }
}

Statistics

SDK provides access to user statistics which contains information about amount of views, clicks, conversions, earned bonus points and current bonus points balance.

import eu.adcharge.api.entities.Statistics;
import eu.adcharge.sdk.logic.AdCharge;

static class GetUserStatisticsTask extends AsyncTask {
    private AdCharge adCharge;

    GetUserStatisticsTask(AdCharge adCharge) {
        this.adCharge = adCharge;
    }

    @Override
    protected Object doInBackground(Object[] objects) {
        try {
            Date now = new Date();
            Date past24hours = new Date(now.getTime() - 24 * 60 * 60 * 1000);
            Statistics statistics = adCharge.getApiWrapper().getStatistics(past24hours, now);
            // Views: statistics.getViews()
            // Clicks: statistics.getClicks()
            // Actions: statistics.getActions()
            // Earned Bonuses: statistics.getBonuses()
            //
            // Current Balance for all time: statistics.getBalance()
        } catch (ApiException | IOException | ApiValidationException e) {
            // do nothing
        }
        return null;
    }
}

Settings

SDK behavior might be customized with settings. Settings are provided as a parameter in constructor (see AdChargeDependentCode.initAdcharge(..) method)

private static final AdCharge.Settings SETTINGS = new AdCharge.Settings();
final AdCharge adCharge = new AdCharge(URL, activity, SETTINGS);

Default values might be overwritten like (after explanation you will find full setting object to use)

  • Do not ask user for location permission (need to be discussed if IP based location targeting allowed for this app as traffic source, ask your manager)
    private static final AdCharge.Settings SETTINGS = new AdCharge.Settings().useLocation(false) // or .useLocation(true)
    
  • Enable/disable advertisement upon incoming call
    private static final AdCharge.Settings SETTINGS = new AdCharge.Settings().showAdsOnCall(true)// or .showAdsOnCall(false)
    
  • Configuration of small banner upon a call
        private static final AdCharge.Settings.SmallBanner SMALL_BANNER_SETTINGS = new AdCharge.Settings.SmallBanner()
        private static final AdCharge.Settings SETTINGS = new AdCharge.Settings().smallBanner(SMALL_BANNER_SETTINGS)
    
    • Display or not small banner (need to be discussed with AdCharge, if allowed to skip small banner)
      private static final AdCharge.Settings.SmallBanner SMALL_BANNER_SETTINGS = new AdCharge.Settings.SmallBanner()
              .enable(true)
              // or .enable(false)
      
    • Initial placement of small banner on screen (middle, top or bottom)
      private static final AdCharge.Settings.SmallBanner SMALL_BANNER_SETTINGS = new AdCharge.Settings.SmallBanner()
              .initialPosition(AdCharge.Settings.SmallBanner.InitialPosition.MIDDLE)
              // or AdCharge.Settings.SmallBanner.InitialPosition.TOP
              // or AdCharge.Settings.SmallBanner.InitialPosition.BOTTOM
      
    • Small banner draggable vertically and you can select draggable area( whole banner, drag icon or not draggable)
      private static final AdCharge.Settings.SmallBanner SMALL_BANNER_SETTINGS = new AdCharge.Settings.SmallBanner()
              .dragSensitiveArea(AdCharge.Settings.SmallBanner.DragSensitiveArea.HOLE_BANNER)
              // or .dragSensitiveArea(AdCharge.Settings.SmallBanner.DragSensitiveArea.DRAG_ICON)
              // or .dragSensitiveArea(AdCharge.Settings.SmallBanner.DragSensitiveArea.NONE)
      
    • There's drag icon on small banner and you may hide it
      private static final AdCharge.Settings.SmallBanner SMALL_BANNER_SETTINGS =   new AdCharge.Settings.SmallBanner()
               .dragIconDisplayed(false)
               // or .dragIconDisplayed(true)
      
  • Configuration of large banner upon a call
        private static final AdCharge.Settings.LargeBanner LARGE_BANNER_SETTINGS = new AdCharge.Settings.LargeBanner()
        private static final AdCharge.Settings SETTINGS = new AdCharge.Settings().largeBanner(LARGE_BANNER_SETTINGS)
    
    • Display or not current bonus points of user on large banner
      private static final AdCharge.Settings.SmallBanner SMALL_BANNER_SETTINGS = new AdCharge.Settings.SmallBanner()
              .bonusPointsBalanceDisplayed(false)
              // or .bonusPointsBalanceDisplayed(true)
      
  • Notification properties
    private static final AdCharge.Settings.NotificationProperties NOTIFICATION_SETTINGS = new AdCharge.Settings.NotificationProperties()
            .showBigIcon(true)
            //      or .showBigIcon(true)
            .title("notification title here")
            //      by default will be '<app name>'
            .text("notification title here");
            //      by default will be 'Tap to open <app name>'
            .activityClassToOpen(ClassOfActivityToBeLaunchedOnClick.class)
            //      by default launcher will be used
  • Full settings object
        private static AdCharge.Settings ADCHARGE_SETTINGS = new AdCharge.Settings()
                // # Ask user for location
                .useLocation(false)
                //       or .useLocation(true)
                .showAdsOnCall(true)
                //       or .showAdsOnCall(false)
                // # Configuration of incoming call small banner
                .smallBanner(
                        new AdCharge.Settings.SmallBanner()
                                // # show or do not show small banner
                                .enable(true)
                                //       or .enable(false)
                                //
                                // # initial placement on screen
                                .initialPosition(AdCharge.Settings.SmallBanner.InitialPosition.MIDDLE)
                                //       or .initialPosition(AdCharge.Settings.SmallBanner.InitialPosition.TOP)
                                //       or .initialPosition(AdCharge.Settings.SmallBanner.InitialPosition.BOTTOM)
                                //
                                // # chose draggable area
                                .dragSensitiveArea(AdCharge.Settings.SmallBanner.DragSensitiveArea.HOLE_BANNER)
                                //       or .dragSensitiveArea(AdCharge.Settings.SmallBanner.DragSensitiveArea.DRAG_ICON)
                                //       or .dragSensitiveArea(AdCharge.Settings.SmallBanner.DragSensitiveArea.NONE)
                                //
                                // # display or hide 'drag icon'
                                .dragIconDisplayed(false)
                                //       or .dragIconDisplayed(true)
                )
                // # Configuration of incoming call large banner
                .largeBanner(
                       new AdCharge.Settings.LargeBanner()
                                // # show or do not show current user bonus points on large banner
                                .bonusPointsBalanceDisplayed(false)
                                //       or .bonusPointsBalanceDisplayed(true)
                )
                .notificationProperties(
                        new AdCharge.Settings.NotificationProperties()
                                .showBigIcon(true)
                                //       or .showBigIcon(true)
                                .title("notification title here")
                                //       by default will be '<app name>'
                                .text("notification title here")
                                //       by default will be 'Tap to open <app name>'
                                .activityClassToOpen(ClassOfActivityToBeLaunchedOnClick.class)
                                //       by default launcher will be used
                );
    
⚠️ **GitHub.com Fallback** ⚠️