From bdf1c40b6a577afca9adfa777ef86681e1a919a8 Mon Sep 17 00:00:00 2001 From: Yordan Banev Date: Mon, 5 Nov 2018 14:23:44 +0200 Subject: [PATCH] Add Interstitial ads as a new proxy. Remove some duplications. --- android/documentation/index.md | 98 ++++++++++++++++++- android/example/app.js | 58 ++++++++++- android/src/ti/admob/AdmobModule.java | 18 ++-- android/src/ti/admob/CommonAdListener.java | 59 +++++++++++ android/src/ti/admob/InterstitialAdProxy.java | 73 ++++++++++++++ android/src/ti/admob/View.java | 25 +---- 6 files changed, 287 insertions(+), 44 deletions(-) create mode 100644 android/src/ti/admob/CommonAdListener.java create mode 100644 android/src/ti/admob/InterstitialAdProxy.java diff --git a/android/documentation/index.md b/android/documentation/index.md index 3a85b2a7..2d798681 100644 --- a/android/documentation/index.md +++ b/android/documentation/index.md @@ -79,12 +79,41 @@ returns the constant for AD_RECEIVED -- for use in an event listener ### `Admob.AD_NOT_RECEIVED` -returns the constant for AD_NOT_RECEIVED -- for use in an event listener +returns whenever the ad was not successfully loaded. The callback contains the +error code in its parameter under the key `errorCode` +Error codes for Android can be checked here: +https://developers.google.com/android/reference/com/google/android/gms/ads/AdRequest#ERROR_CODE_INTERNAL_ERROR #### Example: - adMobView.addEventListener(Admob.AD_NOT_RECEIVED, function () { - alert('ad was not received'); + adMobView.addEventListener(Admob.AD_NOT_RECEIVED, function (e) { + alert('ad was not received. error code is ' + e.errorCode); + }); + +### `Admob.AD_OPENED` + +returns the constant for AD_OPENED -- for use in an event listener + +#### Example: + + adMobView.addEventListener(Admob.AD_OPENED, function () { + alert('ad was just opened'); + }); + +### `Admob.AD_CLOSED` + +#### Example: + + adMobView.addEventListener(Admob.AD_CLOSED, function () { + alert('ad was just closed'); + }); + +### `Admob.AD_LEFT_APPLICATION` + +#### Example: + + adMobView.addEventListener(Admob.AD_LEFT_APPLICATION, function () { + alert('user just left the application through the ad'); }); ### `AdMobView.requestAd(args)` @@ -231,6 +260,69 @@ View the [change log](changelog.html) for this module. Please direct all questions, feedback, and concerns to [info@appcelerator.com](mailto:info@appcelerator.com?subject=Android%20Admob%20Module). +### Interstitial ads + +Starting from 4.4.0 this module now supports Interstitial ads for Android. + +Interstitial ads are full screen ads that are usually shown between natural steps of an application's interface flow. +For instance doing different tasks in your application or between reading different articles. + +For best user experience Interstitial ads should be loaded prior showing the to the user. Interstitial ad instances can +be used for showing one ad per loading, but they can be used multiple times. A good way of reusing an Interstitial ad is +to show an ad, load a new after it has been closed one, and await for the proper time to show the recently loaded. + +#### Properties + +##### adUnitId + +Id for this add. This property can be set in the creation dictionary or after creating the Interstitial ad instance. + +#### Methods + +##### setAdUnitId(String id) + +Sets the adUnitId property. + +##### getAdUnitId() + +Gets the adUnitId property. + +##### load() + +Loads an ad for this Interstitial ad instance. + +##### show() + +Shows an Interstitial ad if there is one successfully loaded. + +#### Example: + + // Create an Interstitial ad with a testing AdUnitId + var interstitialAd = Admob.createInterstitialAd({ adUnitId:"ca-app-pub-3940256099942544/1033173712" }); + + // Add all listeners for the add. + interstitialAd.addEventListener(Admob.AD_CLOSED, function () { + Ti.API.info('Interstitial Ad closed!'); + }); + interstitialAd.addEventListener(Admob.AD_RECEIVED, function () { + // When a new Interstitial ad is loaded, show it. + Ti.API.info('Interstitial Ad loaded!'); + interstitialAd.show(); + }); + interstitialAd.addEventListener(Admob.AD_CLICKED, function () { + Ti.API.info('Interstitial Ad clicked!'); + }); + interstitialAd.addEventListener(Admob.AD_NOT_RECEIVED, function (e) { + Ti.API.info('Interstitial Ad not received! Error code = ' + e.errorCode); + }); + interstitialAd.addEventListener(Admob.AD_OPENED, function () { + Ti.API.info('Interstitial Ad opened!'); + }); + interstitialAd.addEventListener(Admob.AD_LEFT_APPLICATION, function () { + Ti.API.info('Interstitial Ad left application!'); + }); + interstitialAd.load(); + ## Author Brian Kurzius | bkurzius@gmail.com diff --git a/android/example/app.js b/android/example/app.js index 3ab23e9a..83fffb07 100644 --- a/android/example/app.js +++ b/android/example/app.js @@ -6,7 +6,7 @@ */ var win = Titanium.UI.createWindow({ - backgroundColor: "#FFFFFF" + backgroundColor: "#FFFFFF" }); // require AdMob @@ -20,7 +20,7 @@ if (code != Admob.SUCCESS) { // then create an adMob view var adMobView = Admob.createView({ - publisherId:"<>", + adUnitId:"ca-app-pub-3940256099942544/6300978111", testing:false, // default is false //top: 10, //optional //left: 0, // optional @@ -37,6 +37,37 @@ var adMobView = Admob.createView({ }); +// Create an Interstitial ad with a testing AdUnitId +var interstitialAd = Admob.createInterstitialAd({ adUnitId:"ca-app-pub-3940256099942544/1033173712" }); + +// Add all listeners for the add. +interstitialAd.addEventListener(Admob.AD_CLOSED, function () { + Ti.API.info('Interstitial Ad closed!'); + // Once the Interstitial ad is closed disable the button + // until another add is successfully loaded. + showInterstitialAdButton.enabled = false; + showInterstitialAdButton.touchEnabled = false; + interstitialAd.load(); +}); +interstitialAd.addEventListener(Admob.AD_RECEIVED, function () { + // When a new Interstitial ad is loaded, enabled the button. + Ti.API.info('Interstitial Ad loaded!'); + showInterstitialAdButton.enabled = true; + showInterstitialAdButton.touchEnabled = true; +}); +interstitialAd.addEventListener(Admob.AD_CLICKED, function () { + Ti.API.info('Interstitial Ad clicked!'); +}); +interstitialAd.addEventListener(Admob.AD_NOT_RECEIVED, function (e) { + Ti.API.info('Interstitial Ad not received! Error code = ' + e.errorCode); +}); +interstitialAd.addEventListener(Admob.AD_OPENED, function () { + Ti.API.info('Interstitial Ad opened!'); +}); +interstitialAd.addEventListener(Admob.AD_LEFT_APPLICATION, function () { + Ti.API.info('Interstitial Ad left application!'); +}); +interstitialAd.load(); //listener for adReceived adMobView.addEventListener(Admob.AD_RECEIVED,function(){ @@ -44,6 +75,11 @@ adMobView.addEventListener(Admob.AD_RECEIVED,function(){ Ti.API.info("ad received"); }); +adMobView.addEventListener('ad_clicked', function(){ + // alert("ad received"); + Ti.API.info("ad clicked"); +}); + //listener for adNotReceived adMobView.addEventListener(Admob.AD_NOT_RECEIVED,function(){ //alert("ad not received"); @@ -73,16 +109,23 @@ adRequestBtn2.addEventListener("click",function(){ adMobView.requestTestAd(); }); +var showInterstitialAdButton = Ti.UI.createButton({ + title: "Show Interstitial", + top: "40%", + height: "10%", + width: "80%" +}) + var getAAID = Ti.UI.createButton({ title: "Get AAID", - top: "40%", + top: "55%", height: "10%", width: "80%" }); var getIsAdTrackingLimited = Ti.UI.createButton({ title: "Is Ad tracking limited", - top: "55%", + top: "70%", height: "10%", width: "80%" }); @@ -97,11 +140,16 @@ getIsAdTrackingLimited.addEventListener('click', function() { Admob.isLimitAdTrackingEnabled(function (data) { Ti.API.info('Ad tracking is limited: ' + data.isLimitAdTrackingEnabled); }); -}) +}); + +showInterstitialAdButton.addEventListener('click', function () { + interstitialAd.show(); +}); win.add(adMobView); win.add(adRequestBtn); win.add(adRequestBtn2); +win.add(showInterstitialAdButton); win.add(getAAID); win.add(getIsAdTrackingLimited) win.open(); \ No newline at end of file diff --git a/android/src/ti/admob/AdmobModule.java b/android/src/ti/admob/AdmobModule.java index 54eab9f0..237f4de6 100644 --- a/android/src/ti/admob/AdmobModule.java +++ b/android/src/ti/admob/AdmobModule.java @@ -65,20 +65,8 @@ public class AdmobModule extends KrollModule public static String PUBLISHER_ID; - // constants - @Kroll.constant public static final int AD_TYPE_BANNER = 0; - @Kroll.constant public static final int AD_TYPE_INTERSTITIAL = 1; - @Kroll.constant public static final String AD_RECEIVED = "ad_received"; - @Kroll.constant public static final String AD_NOT_RECEIVED = "ad_not_received"; - @Kroll.constant public static final int SUCCESS = 0; - @Kroll.constant public static final int SERVICE_MISSING = 1; - @Kroll.constant public static final int SERVICE_VERSION_UPDATE_REQUIRED = 2; - @Kroll.constant public static final int SERVICE_DISABLED = 3; - @Kroll.constant public static final int SERVICE_INVALID = 9; - // properties public static String PROPERTY_AD_UNIT_ID = "adUnitId"; - public static String PROPERTY_AD_TYPE = "adType"; public static String PROPERTY_DEBUG_ENABLED = "debugEnabled"; public static String PROPERTY_TESTING = "testing"; public static String PROPERTY_PUBLISHER_ID = "publisherId"; @@ -102,6 +90,12 @@ public AdmobModule() public static final String AD_RECEIVED = "ad_received"; @Kroll.constant public static final String AD_NOT_RECEIVED = "ad_not_received"; + @Kroll.constant + public static final String AD_CLOSED = "ad_closed"; + @Kroll.constant + public static final String AD_OPENED = "ad_opened"; + @Kroll.constant + public static final String AD_LEFT_APPLICATION = "ad_left_application"; // Response from "isGooglePlayServicesAvailable()"" @Kroll.constant diff --git a/android/src/ti/admob/CommonAdListener.java b/android/src/ti/admob/CommonAdListener.java new file mode 100644 index 00000000..a800531b --- /dev/null +++ b/android/src/ti/admob/CommonAdListener.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2011 by Studio Classics. All Rights Reserved. + * Copyright (c) 2017-present by Axway Appcelerator. All Rights Reserved. + * Licensed under the terms of the Apache Public License + * Please see the LICENSE included with this distribution for details. + */ + +package ti.admob; + +import com.google.android.gms.ads.AdListener; + +import org.appcelerator.kroll.KrollDict; +import org.appcelerator.kroll.KrollProxy; +import org.appcelerator.kroll.common.Log; + +public class CommonAdListener extends AdListener { + + private KrollProxy sourceProxy; + private String sourceTag; + + public CommonAdListener(KrollProxy sourceProxy, String tag) { + this.sourceProxy = sourceProxy; + this.sourceTag = tag; + } + + @Override + public void onAdLoaded() { + Log.d(this.sourceTag, "onAdLoaded()"); + this.sourceProxy.fireEvent(AdmobModule.AD_RECEIVED, new KrollDict()); + } + + @Override + public void onAdFailedToLoad(int errorCode) + { + super.onAdFailedToLoad(errorCode); + Log.d(this.sourceTag, "onAdFailedToLoad(): " + errorCode); + KrollDict eventData = new KrollDict(); + eventData.put("errorCode", String.valueOf(errorCode)); + this.sourceProxy.fireEvent(AdmobModule.AD_NOT_RECEIVED, eventData); + } + + @Override + public void onAdClosed() { + super.onAdClosed(); + this.sourceProxy.fireEvent(AdmobModule.AD_CLOSED, new KrollDict()); + } + + @Override + public void onAdOpened() { + super.onAdOpened(); + this.sourceProxy.fireEvent(AdmobModule.AD_OPENED, new KrollDict()); + } + + @Override + public void onAdLeftApplication() { + super.onAdLeftApplication(); + this.sourceProxy.fireEvent(AdmobModule.AD_LEFT_APPLICATION, new KrollDict()); + } +} \ No newline at end of file diff --git a/android/src/ti/admob/InterstitialAdProxy.java b/android/src/ti/admob/InterstitialAdProxy.java new file mode 100644 index 00000000..2ed2a014 --- /dev/null +++ b/android/src/ti/admob/InterstitialAdProxy.java @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2011 by Studio Classics. All Rights Reserved. + * Copyright (c) 2017-present by Axway Appcelerator. All Rights Reserved. + * Licensed under the terms of the Apache Public License + * Please see the LICENSE included with this distribution for details. + */ + +package ti.admob; + +import com.google.android.gms.ads.AdRequest; +import com.google.android.gms.ads.InterstitialAd; + +import org.appcelerator.kroll.KrollDict; +import org.appcelerator.kroll.KrollProxy; +import org.appcelerator.kroll.annotations.Kroll; +import org.appcelerator.kroll.common.Log; + +@Kroll.proxy(creatableInModule = AdmobModule.class) +public class InterstitialAdProxy extends KrollProxy { + + private final String TAG = "InterstitialAd"; + private InterstitialAd interstitialAd; + + public InterstitialAdProxy() { + this.interstitialAd = new InterstitialAd(getActivity()); + this.interstitialAd.setAdListener(new CommonAdListener(this, TAG)); + } + + @Override + public void handleCreationDict(KrollDict dict) { + super.handleCreationDict(dict); + if (dict.containsKeyAndNotNull(AdmobModule.PROPERTY_AD_UNIT_ID)) { + this.interstitialAd.setAdUnitId(dict.getString(AdmobModule.PROPERTY_AD_UNIT_ID)); + } + } + + // clang format off + @Kroll.method + @Kroll.setProperty + public void setAdUnitId(String adUnitId) + // clang format on + { + // Validate the parameter + if (adUnitId != null && adUnitId instanceof String) { + this.interstitialAd.setAdUnitId(adUnitId); + } + } + + // clang format off + @Kroll.method + @Kroll.getProperty + public String getAdUnitId() + // clang format on + { + return this.interstitialAd.getAdUnitId(); + } + + @Kroll.method + public void load() + { + this.interstitialAd.loadAd(new AdRequest.Builder().build()); + } + + @Kroll.method + public void show() + { + if (this.interstitialAd.isLoaded()) { + this.interstitialAd.show(); + } else { + Log.w(TAG, "Trying to show an ad that has not been loaded."); + } + } +} \ No newline at end of file diff --git a/android/src/ti/admob/View.java b/android/src/ti/admob/View.java index 9dadd3ed..92d5a0d3 100644 --- a/android/src/ti/admob/View.java +++ b/android/src/ti/admob/View.java @@ -59,19 +59,7 @@ private void createAdView() adView.setAdUnitId(prop_adUnitId); // set the listener - adView.setAdListener(new AdListener() { - public void onAdLoaded() - { - Log.d(TAG, "onAdLoaded()"); - proxy.fireEvent(AdmobModule.AD_RECEIVED, new KrollDict()); - } - - public void onAdFailedToLoad(int errorCode) - { - Log.d(TAG, "onAdFailedToLoad(): " + errorCode); - proxy.fireEvent(AdmobModule.AD_NOT_RECEIVED, new KrollDict()); - } - }); + adView.setAdListener(new CommonAdListener(proxy, TAG)); adView.setPadding(prop_left, prop_top, prop_right, 0); // Add the AdView to your view hierarchy. // The view will have no size until the ad is loaded. @@ -108,17 +96,6 @@ public void processProperties(KrollDict d) if (d.containsKey(AdmobModule.PROPERTY_AD_UNIT_ID)) { prop_adUnitId = d.getString(AdmobModule.PROPERTY_AD_UNIT_ID); } - if (d.containsKey(AdmobModule.PROPERTY_AD_TYPE)) { - int type = d.getInt(AdmobModule.PROPERTY_AD_TYPE); - switch (type) { - case AdmobModule.AD_TYPE_BANNER: - prop_adSize = AdSize.BANNER; - break; - case AdmobModule.AD_TYPE_INTERSTITIAL: - prop_adSize = AdSize.FLUID; - break; - } - } if (d.containsKey(AdmobModule.PROPERTY_DEBUG_ENABLED)) { prop_debugEnabled = d.getBoolean(AdmobModule.PROPERTY_DEBUG_ENABLED); }