Disclaimer This document is provided as-is. Information and views expressed in this document, including URL and other Internet Web site references, may change without notice. You bear the risk of using it. This document does not provide you with any legal rights to any intellectual property in any LeadBolt product. You may copy and use this document for your internal, reference purposes. 2013 LeadBolt. All rights reserved. Android is a trademark of the Google Inc. All other logos and trademarks are the property of their respective trademark owners.
App Market places Various app marketplaces apply conditions on app developers that they must comply with, when participating or uploading apps to these marketplaces. Please note, the inclusion of this unified SDK does not transfer that responsibility and it remains the responsibility of the App developer to achieve compliance with any app marketplace conditions. Our SDK includes features and functions to support App developers efforts with marketplace compliance and we strongly recommend including or utilizing those features where possible.
Page 2 of 29
Table of Contents
WHAT'S NEW IN V6.1 ....................................................................................... 4
DISPLAY/AUDIO AD CACHING (NEW) ........................................................................................ 4 AUTO-SCALING BANNERS (NEW) ............................................................................................. 4 PERFORMANCE & AD LOADING SPEED ENHANCEMENTS .................................................................... 5
WORKING WITH 'APP AD' TEMPLATES ........................................................... 12 ADDING A LEADBOLT 'APP AD' TO YOUR APP CODE ....................................... 13
COMPLETING A SIMPLE INTEGRATION ........................................................................................ 13 ADVANCED INTEGRATION WITH CACHING .................................................................................... 14
Page 3 of 29
Display/Audio Ad Caching (new) Displaying in-app advertising seamlessly and without delaying user interaction is essential for high performing ad placements. This SDK includes support for pre-cached ad loading, allowing developers pre-load an ad, ready to be displayed instantly at a later time during app usage. LeadBolts pre-cached ads significantly reduce perceived ad loading time for users and provide a seamless app experience.
Auto-Scaling Banners (new) Supporting multiple resolution devices with banner ads is now easy using LeadBolts auto stretching banner ad type. Auto stretching banner ads automatically scale to match the users screen width, while maintaining the correct aspect ratio and adjusting the height accordingly, to ensure optimal ad display and a cohesive user experience on all devices and screen sizes.
Page 4 of 29
Performance & Ad Loading Speed Enhancements This SDK version includes some highly optimized enhancements delivering even better ad performance and dramatically increased ad loading speed. Overall, this SDK creates a better ad experience for users as well as providing performance enhancements for publishers. Other Changes: Due to requirements outlined in the Google Play developer policy (effective on the 23rd of September 2013 for existing apps), Notification Ads and App Icons are not supported by LeadBolt in this SDK.
Page 5 of 29
Page 6 of 29
INTERNET ACCESS_NETWORK_STATE
Make sure that these are defined in your Project's AndroidManifest.xml file
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Optional permissions that may improve ad serving results through the location based targeting features or assist opt-out are:
Where used, make sure that these are also defined in your Projects AndroidManifest.xml file
<uses-permission <uses-permission <uses-permission <uses-permission android:name="android.permission.READ_PHONE_STATE" /> android:name="android.permission.ACCESS_COARSE_LOCATION"/> android:name="android.permission.ACCESS_FINE_LOCATION"/> android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
Page 7 of 29
Step 2: Add the LeadBolt static library To add the LeadBolt SDK static library, follow these steps: 1. Unzip the downloaded file and then in the Eclipse IDE, simply drag the generated jar file into your Projects libs folder. 2. When prompted Select how files should be imported into the project: and tick Copy Files option and click OK
3. Then, right-click on your Project and click Build Path -> Configure Build Path. 4. Under the window displayed, select Libraries tab. Click Add JARs, then select the jar file from the libs folder of your Project. 5. If you are planning to use ProGuard when exporting your app, you will need to add the following lines of code in your App's ProGuard config file typically located in the root directory on your App and is named proguard.cfg or proguard-project.txt. -keep class com.<sdkpackagename>.** { *; } -keepclassmembers class **.R$* { public static <fields>; } -keep class **.R$*
Page 8 of 29
<service android:name="com.<sdkpackagename>.ReEngagementService"></service> <receiver android:name="com.<sdkpackagename>.ReEngagement" /> <service android:name="com.<sdkpackagename>.AdBootReceiverService"></service> <receiver android:name="< YOUR_APP_PACKAGE_NAME >.BootReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> </application>
Please note: Replace "<YOUR_APP_PACKAGE_NAME>" as noted above with your App's package name NOT the generated package name for this SDK.
Page 9 of 29
Add Required Code To run Quick StartAds in your App, simply need to add a few lines of code into your App. Main App Activity
/* Other imports here */ import com.<sdkpackagename>.AdController; import com.appfireworks.android.track.AppTracker; public class HelloWorld extends Activity { private AdController ad; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ad = new AdController(this, "MY_LB_SECTION_ID"); ad.loadStartAd("MY_LB_AUDIO_ID", "MY_LB_REENGAGEMENT_ID"); AppTracker.startSession(this, "APPFIREWORKS_API_KEY"); } @Override public void onPause() { super.onPause(); if(ad != null) { ad.destroyAd(); } if(!isFinishing()) { AppTracker.pause(getApplicationContext()); } } @Override public void onResume() { super.onResume(); AppTracker.resume(getApplicationContext()); } @Override public void onDestroy() { super.onDestroy(); if(ad != null) { ad.destroyAd(); } AppTracker.closeSession(getApplicationContext(),true); } }
Page 10 of 29
Handling System Reboots To handle device reboots and continue serving Ads, simply add a Boot Receiver file in your App
import android.content.Context; import android.content.Intent; import com.<sdkpackagename>.AdBootReceiver; public class BootReceiver extends AdBootReceiver { public void onReceive(Context ctx, Intent intent) { intent.putExtra("sectionid","YOUR_LB_REENGAGEMENT_ID"); super.onReceive(ctx, intent); // Other App specific code here } }
Page 11 of 29
NEW
Be sure to add all these to your app. All these ad types are available when creating an App Ad by choosing the desired template and then implementing it using the standard App Ad loadAd() function. It is well proven that an ad experience that matches your app will lead to high user engagement. T
Page 12 of 29
Once this code is included, access your publisher portal and add an App Ad (SDK) section and use the get code icon to retrieve the value for MY_LB_SECTION_ID. All Ad formats have Auto-Scaling option, which will scale the Ad to the appropriate size automatically on the Device. However, if your App requires, LeadBolt SDK does support fixed sized banners
Page 13 of 29
Page 14 of 29
Page 15 of 29
private AdController ad; private Boolean adLoaded = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ad = new AdController(this, "YOUR_LB_SECTION_ID", new AdListener() { public void onAdLoaded() { loaded = true; } public void onAdClicked() {} public void onAdClosed() { finish(); } public void onAdCompleted() { finish(); } public void onAdFailed() { finish(); } public void onAdProgress() {} public void onAdAlreadyCompleted() { finish(); } public void onAdPaused() { finish(); } public void onAdResumed() {} public void onAdCached() {} }); ad.loadAdToCache(); // Other App Specific Code here } @Override public boolean onKeyDown(final int keyCode, final KeyEvent event) { if (keyCode== KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { if(!loaded && ad != null) { ad.loadAd(); return true; } } return super.onKeyDown(keyCode, event); }
Page 16 of 29
Once your class implements AdListener, All 10 abstract methods will need to be implemented in your class, as shown below. To utilize these methods just add the app specific code you want to implement.
Page 17 of 29
public void onAdLoaded() { // add app specific code for this event here... // called when an ad is successfully displayed on device } public void onAdClicked() { // add app specific code for this event here... // called when an ad is clicked by user } public void onAdClosed() { // add app specific code for this event here... // called when the ad window is closed by user } public void onAdCompleted() { // add app specific code for this event here... // supported for Overlay template types. // called when ad window is closed with successful conversion } public void onAdFailed() { // add app specific code for this event here... // called when the ad request to the ad server has failed // e.g No Internet connection // if destroyAd needs to be called in this function please use // following code this.runOnUiThread(new Runnable() { public void run() { if(ad != null) { myController.destroyAd(); } } }); } public void onAdProgress() { // add app specific code for this event here... // call every x seconds while ad loading is in progress // x must be set by calling myController.setOnProgressInterval(x); // this function is off by default } public void onAdAlreadyCompleted() { // add app specific code for this event here... // triggered when loadAd() is called & current device has recorded // a successful conversion } public void onAdPaused() { // add app specific code for this event here... // triggered when loadAd() is called & pauseAd() has previously // been called by App Developer } public void onAdCached() { // add app specific code for this event here... // triggered once the Ad is successfully cached // when loadAdToCache is called } public void onAdResumed() { // add app specific code for this event here... // triggered when resumeAd() is called by App Developer }
Page 18 of 29
Now, finally when initializing the AdController class, you will need to pass the AdListener to it, as shown in the example below:
AdController ad = new AdController(this, "MY_LB_SECTION_ID", this); ad.loadAd();
In some cases it may be not suitable or appropriate to have your main activity class implement the AdListener interface. In those cases the following method is recommended.
AdController AdListener() public public public public public public public public public public }); ad.loadAd(); ad = { void void void void void void void void void void new AdController(this, "MY_LB_SECTION_ID", new onAdLoaded() {} onAdClicked() {} onAdClosed() {} onAdCompleted() {} onAdFailed() {} onAdProgress() {} onAdAlreadyCompleted() {} onAdPaused() { } onAdResumed() { } onAdCached() {}
Utilizing Device back button For App Ads, it is also possible for developers to programmatically link the device back button to the full screen ad window back button after an ad is clicked. A function onBackPressed() implements this functionality and also returns true when successfully initiated so that other app-specific code can be executed in this specific scenario. Sample code for linking the back buttons is shown below. It would typically be included in the main activity.
Page 19 of 29
@Override public boolean onKeyDown(final int keyCode, final KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if(ad.onBackPressed()) { // ie ad serving is in progress and back function // to previous ad window successful. // add additional app specific code here for this // scenario... } else { // any app specific code here for back button handling // outside the ad serving process } return true; // i.e tells activity action has been performed for the click } return super.onKeyDown(keyCode, event); }
Adding a Margin for Banner Docking The docking margin for SDK banner ads can be controlled within the app with an additional SDK function to handle device specific adjustments. This setAdditionalDockingMargin() function allows the dynamic adjustment of a banner ad placements vertical position by adding an additional docking margin setting (in pixels) in your publisher portal, for that specific section. This line has to be placed before standard loadAd() function is called. An example usage shown below:
AdController ad = new AdController(act, MY_LEADBOLT_SECTION_ID); // adjust the banner dynamically by 50 pixels from its designated // position ad.setAdditionalDockingMargin(50); ad.loadAd();
Passing Sub Id from App When passing a sub id, you must add the code 'ad.setSubId("YOUR_SUB_ID");' before you call loadAd();
Page 20 of 29
Add the App Re-engagement registration code This is achieved by adding the LeadBolt code inside your onCreate() function. Sample App code is given below showing simplest way to integrate LeadBolt App Re-engagement:
/* Other imports here */ import com.<sdkpackagename>.AdController; public class HelloWorld extends Activity { private AdController re; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); re = new AdController(getApplicationContext(), "MY_LB_REENGAGEMENT_ID"); re.loadReEngagement(); } }
Page 21 of 29
Handle system reboots In order to ensure App Re-engagement can continue to be received after system reboots the following additional code and configuration is required. You will need to add a Boot receiver to the android manifest. This means adding the following lines with the appropriate <YOUR_APP_PACKAGE_NAME> as noted below. Please Note: This will
be your App's package name NOT the generated package name from the Publisher Portal
<application <receiver android:name="<YOUR_APP_PACKAGE_NAME>.BootReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> </application>
Then you will need to create a new file for the boot receiver, name it BootReceiver.java which extends the AdBootReceiver class from the LeadBolt SDK and add the following code with your section id.:
import android.content.Context; import android.content.Intent; import com.<sdkpackagename>.AdBootReciver; public class BootReceiver extends AdBootReceiver { public void onReceive(Context ctx, Intent intent) { intent.putExtra("sectionid", "YOUR_REENGAGEMENT_ID"); super.onReceive(ctx, intent); } }
Page 22 of 29
You can also run Audio Ads anywhere else in your Activity. You simply need to run the following lines in the appropriate function of your Activity class. Allow sufficient time for the audio ad to play before calling this function again.
AdController audioad = new AdController(this, "MY_LB_SECTION_ID"); audioad.loadAudioAd();
Page 23 of 29
Audio Ad Caching This SDK includes support for pre-cached ad loading, allowing you to pre-load an ad, ready to be displayed at a later time during app usage. This significantly reduces the ad loading time, as perceived by a user. To add a caching "Audio Ad (SDK)" to your app, use the code below:
/* Other imports here */ import com.<sdkpackagename>.AdController; public class HelloWorld extends Activity { Private AdController audio; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); audio = new AdController(this, "MY_LB_SECTION_ID", new AdAudioListener() { public void onAdProgress() {} public void onAdLoaded() {} public void onAdFinished() {} public void onAdFailed() {} public void onAdClosed() {} public void onAdClicked() {} public void onAdCached() { // called when Audio is successfully cached Audio.loadAd(); } }); audio.loadAudioAdToCache(); } }
Page 24 of 29
Audio Ad Event Listeners Audio Ads have their own set of Event Listeners which will assist App Developers listening to the ad progress throughout the lifecycle of the Audio Ad. Event listeners exist for Audio Ad loading, Audio Ad click (when a valid device shake is detected), closures, finishes, failures and Audio Ad progress. Below is some sample code that implements the Event Listeners so that these events can be handled during the lifecycle of the Audio Ad by the developer.
AdController audio = new AdController(this, "YOUR_LB_SECTION_ID", new AdAudioListener() { public void onAdProgress() { // called every x secs till audio ad is loaded or destroyed // audioAd.setOnProgressInterval(x); needs to be called // prior to calling loadAudioAd for the function to be triggered } public void onAdLoaded() { // called when audio ad is successfully loaded to be played } public void onAdFinished() { // called when audio ad finishes playing or a valid // user shake is detected } public void onAdFailed() { // called when audio ad fails to be loaded } public void onAdClosed() { // called when app developer calls audioAd.destroyAd() in the code } public void onAdClicked() { // called when a valid device shake is received // and user is taken to the ad offer. } public void onAdCached() { // called when Audio is successfully cached after // loadAudioAdToCache() is called } }); /* OPTIONAL SETTINGS: To trigger onAdProgress every 2 secs till the Audio is loaded, add the line below to your code. Change the integer value that is appropriate to your App. audio.setOnProgressInterval(2); */ audio.loadAudioAd();
Page 25 of 29
Audio Tracks LeadBolts Audio Tracks allow you to set auto play audio ads during app usage, on a set timeline of your choice. This is the ultimate set-andforget ad integration which allows you to continue monetizing active users, no matter how long they use your app for. Below is the sample code which shows how to run Audio Tracks throughout app usage:
/* Other imports here */ import com.<sdkpackagename>.AdController; public class HelloWorld extends Activity { private AdController audio; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); AdController audio = new AdController(this, "MY_LB_AUDIO_ID"); audio.loadAudioTrack(2); // value in mins // determines after how many mins to start the Audio Track. Change the value of 2 to suit your App. } @Override protected void onPause() { super.onPause(); if(audio != null) { audio.destroyAd(); } } @Override protected void onDestroy() { super.onDestroy(); if(audio != null) { audio.destroyAd(); } } @Override protected void onResume() { super.onResume(); if(audio == null) { audio = new AdController(this, "MY_LB_AUDIO_ID"); } audio.loadAudioTrack(1); // value in mins // Change the Interval to suit your App } }
Copyright 2013. LeadBolt. All rights reserved Page 26 of 29
AppFireworks Analytics
LeadBolt is bundling an awesome in-app analytics platform (AppFireworks) for free! Including AppFireworks analytics in your app will deliver deep insights into app usage, user behavior, retention and user engagement, as well as giving you access to a wide range of powerful developer tools including cross promotion, ad mediation, install tracking and much more! To integrate AppFireworks analytics into your app, you can follow the steps below, read our Quick Start Ad Guide or simply utilize the AppFireworks SDK documentation available from AppFireworks.
Required Permissions
The following permissions are required to integrate AppFireworks into your app. These permissions are also required by the LeadBolt SDK:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Page 27 of 29
AppFireworks Code
Add the following code to your app, ensuring that the APPFIREWORKS_API_KEY is replaced with your unique AppFireworks key:
/* Other imports here */ import com.appfireworks.android.track.AppTracker; public class HelloWorld extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); AppTracker.startSession(this, "APPFIREWORKS_API_KEY"); } @Override public void onPause() { super.onPause(); if(!isFinishing()) { AppTracker.pause(getApplicationContext()); } } @Override public void onResume() { super.onResume(); AppTracker.resume(getApplicationContext()); } @Override public void onDestroy() { super.onDestroy(); AppTracker.closeSession(getApplicationContext(),true); }
Page 28 of 29
Page 29 of 29