So how on earth do you get ads to correctly show in a AIR for Android application running on phone? This question has stumped me for a while now and with help from Ian Stokes (http://www.munchiegames.com/) I’ve managed to get it working. There seems to be still some problems with it, but at least this post should help other developers get up to speed with what necessary to get it running.
UPDATE: Xavi Vives (@xavivives) discovered that the problem of ads no showing up was in fact due to there being no ads to show! The solution is to create you own ‘House Ad’ that gets shown when there are no network ads available. Xavi has a web post that has a class setup to manage the ad placement. Check out his post here – http://xavivives.com/how-to-insert-and-properly-display-admob-on-air-for-android
I assume you already know how to publish an app to an Android phone. What I will do is set up a basic demo file showing how this works, give source and a quick, rough explanation.
To display an advert within an AIR app you need to be able to load a webpage containing the adverts code. For this example I am using AdMob (I haven’t had a chance to try it with any others). This is achieved by using a ‘new’ class named ‘StageWebView’, The official documents on StageWebView are here on Adobe’s AS3 reference site.
A few notes about StageWebView:
- It is only available to AIR 2.5 (and above) applications, if you try publishing a normal swf you will receive compile/runtime errors. (eg: VerifyError: Error #1014: Class flash.media::StageWebView could not be found.)
- Effectively creates a ‘window’ separate from all normal display list items in which you can load HTML content.
- This ‘window’ sits above all other content on the stage and will effectively cover it
- It gives you very little control of the content you load into this ‘window’, you cannot rotate or change alpha.
- You can set the size of the ‘window’ you load content in, the URL you load in, receive events when the content changes
So lets cover some basics. In it’s simplest form you can create a StageWebView window and load content like this …
Remember you need to setup the publishing as an AIR 2.5+ file or it will fail.
1 2 3 4 5 6 7 8 9 10 | // create instance of StageWebView var _stageWebView:StageWebView = new StageWebView (); _stageWebView.stage = stage // set the size and location of the html 'window' // in this case x = 0, y=0, width = 480px, height = 80px _stageWebView.viewPort = new Rectangle(0,0,480,80); // url of html we want to load var myAdvertURL:String = "http://terrypaton.com/ads/exampleAdvert.html"; // load the html page in to our StageWebView instance _stageWebView.loadURL(myAdvertURL); |
This will load a html page and display it
What this should display is the following (when run as a desktop AIR app) …
![]()
Ok, so that’s all really easy and good, but lets move on to a more complicated example. This example/src code will have options to create, hide and destroy the StageWebView, and also react correctly to a click on the ad itself – all useful when showing ads within games and applications.
One important thing in we need to do when incorporating adverts in StageWebView is monitoring when the content of the html changes, as it will continue to load within the StageWebView instance, which is only sized at 80px high. We do this by adding a listener to the StageWebView instance for LocationChangeEvent.LOCATION_CHANGE event and using navigateToURL with the intercepted URL.
1 2 3 4 | // note: this is simplified function onLocationChange(event:LocationChangeEvent):void { navigateToURL( new URLRequest( event.location ) ); } |
Now testing on the desktop this all works fine, the ad loads nicely, but for some reason beyond me the scaling and position of my ad are wildly off. I did the following test with just a simple jpg linked to a url, I am terrible at HTML (and have no interest) so I’m not sure why this happens. In the following video I demonstrate the problem.
normalHtml from Terry Paton on Vimeo.
This is the HTML is the video example above – if I’ve done something wrong, please point it out …
1 2 3 4 | < !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <body> <a href="http://www.terrypaton.com/"><img src="http://www.terrypaton.com/ads/exampleAdvert.jpg" alt="advert" width="480" height="60" /></a> </body> |
And that’s where I almost gave up, until Ian Stokes confirmed he had it working with on of his games games while using AdMob. Turns out Admob have magical javascript that sizes the ad correctly when used on a mobile device, something I didn’t try until Ian mentioned it. I won’t go into the details of setting up an ad in Admob, but I did try to use the various ad formats/code they supply and only one worked – ‘Smartphone web’
Here’s the HTML file code with Admob, NOTE: I’ve replaced my publisher ID with XXXXXXXXXXXXXXX – put your own there, also this is in testing mode – see line 10.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | < !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <body bgcolor="#000000"> <script type="text/javascript"> var admob_vars = { pubid: 'XXXXXXXXXXXXXXX', // publisher id bgcolor: '000000', // background color (hex) text: 'FFFFFF', // font-color (hex) ama: false, // set to true and retain comma for the AdMob Adaptive Ad Unit, a special ad type designed for PC sites accessed from the iPhone. More info: http://developer.admob.com/wiki/IPhone#Web_Integration test: true // test mode, set to false to receive live ads }; </script> <script type="text/javascript" src="http://mmv.admob.com/static/iphone/iadmob.js"></script> </body> |
Now running the AdMob in test mode works fine, and it displays the ad correctly as demostrated in the video below …
AdmobTest from Terry Paton on Vimeo.
But the weird thing is when switching to real ads, the ads don’t always show which may be due to AdMob putting limits on how many ads they show to IP addresses or something else. If you have an idea why this might be happening, I’d love your help.
Here’s a video showing the ads loading correctly (after I tried loading them about 6 times) …
AdMobReal from Terry Paton on Vimeo.
Here’s the code used in my example files …
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | // imports import flash.events.Event; import flash.events.LocationChangeEvent; import flash.geom.Rectangle; import flash.media.StageWebView; import flash.net.navigateToURL; import flash.net.URLRequest; import flash.events.MouseEvent; // setup variables var _stageWebView:StageWebView; var myAdvertURL:String = "http://terrypaton.com/ads/exampleAdvert.html"; // function createAd(event:MouseEvent):void { // check that _stageWebView doersn't exist if (! _stageWebView) { _stageWebView = new StageWebView () ; // set the size of the html 'window' _stageWebView.viewPort = new Rectangle(0,0,480,80); // add a listener for when the content of the StageWebView changes _stageWebView.addEventListener(LocationChangeEvent.LOCATION_CHANGE,onLocationChange); // start loading the URL; _stageWebView.loadURL(myAdvertURL); } // show the ad by setting it's stage property; _stageWebView.stage = stage; } function toggleAd(event:MouseEvent):void { trace("toggling advert",_stageWebView); // check that StageWebView instance exists if (_stageWebView) { trace("_stageWebView.stage:"+_stageWebView.stage); if (_stageWebView.stage == null) { //show the ad by setting the stage parameter _stageWebView.stage = stage; } else { // hide the ad by nulling the stage parameter _stageWebView.stage = null; } } else { // ad StageWebView doesn't exist - show create it createAd(null); } } function destroyAd(event:MouseEvent):void { // check that the instace of StageWebView exists if (_stageWebView) { trace("removing advert"); // destroys the ad _stageWebView.stage = null; _stageWebView = null; } } function onLocationChange(event:LocationChangeEvent):void { // check that it's not our ad URL loading if (_stageWebView.location != myAdvertURL) { // stop the content from loading within StageWebView event.preventDefault(); // Launch a normal browser window with the captured URL; navigateToURL( new URLRequest( event.location ) ); } } // setup button listeners createAdBtn.addEventListener(MouseEvent.CLICK,createAd); toggleAdBtn.addEventListener(MouseEvent.CLICK,toggleAd); destroyAdBtn.addEventListener(MouseEvent.CLICK,destroyAd); |
I’ve set this up as timeline code in Flash CS5 to make it a little more accesible. There are 3 MovieClips acting as buttons ‘createAdBtn’, ‘toggleAdBtn’ and ‘destroyAdBtn’
DOWNLOAD SOURCE FILES ![]()
Note the source files contain an already compiled .apk you can install on your Android phone).
Important notes:
You’ll need to use your own certificate and password when publishing
You will need to make sure your Android permissions allow Internet access in order to load ads.
