RSS
 

AdMob adverts in AIR for Android applications

13 Feb

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.

 

Tags: , , , ,

  • Samuel Otero

    This was very helpful! Thank Terry

  • Sonic

    Thanks for sharing. : )

  • james

    Nice job, Terry.
    Try removing the width=”480″ attribute from the html you had trouble with.

  • http://www.terrypaton.com Terry Paton

    Thanks for the tip, unfortunately it didn’t make any difference. I used this …

    and it still comes in zoomed :S

  • james

    You’re right. I tried it myself on my evo shift and sometimes it is zoomed in and sometimes it is zoomed out. If I figure it out later, I’ll let you know. Please let me know if you figure it out as now I’m curious :)

  • james

    Looks like it’s using your browser’s automatic zoom settings. I set mine to FAR and added the meta tag

    To a head tag on the HTML and it worked. I wonder if there is a way to do it without having to change the browser setting?

  • james

    Found the solution and explanation…
    http://davidbcalhoun.com/2010/viewport-metatag

  • http://www.terrypaton.com Terry Paton

    Hmm, still not working for me on my Nexus S, I tried all the settings listed and didn’t seem to work for me. I’ll give it another go when I have more time and see what I can do. Thanks for the tip though.

  • John

    It doesn’t seem to like serving ads large then 320×60.

    Is there a way to make this work for tablets, or other devices with large then iPhone sized screens?

  • http://www.dream-maidens.com Chykara

    thanks. I am going to try this later on. Horray for Ian!

  • http://www.dream-maidens.com Chykara

    Okay I managed to get this working, but I still have a space above the ad. It seems like you got it to work without the spacing, am I doing something wrong in the html file?

  • http://www.dream-maidens.com Chykara

    Nevermind I have it working properly. In my body tag I inserted TOPMARGIN=0 LEFTMARGIN=0 MARGINHEIGHT=0 MARGINWIDTH=0 and it removed the white space if anyone else is having the same problem. Thanks so much for this helpful tutorial! Key and I give you many many thank yous! Arigatou ^_^

  • Seth

    For the life of me, I cannot get this test app to work. I created my own html page, and I can see the test ad if i go straight to the URL via the phone’s web browser. But when I run the app (which loads the same exact URL via StageWebView), the test ad doesn’t show up. I know its loading the html page though, cause I can see the background color specified in the html code in the StageWebView. Any ideas where I’m going wrong?

  • Seth

    Oh, and I literally copied and pasted your AS code from above. So again, it should be working. Argghh

  • http://www.terrypaton.com Terry Paton

    Hey ya Seth, it’s a bit difficult know what could be wrong. Have you tried ‘clicking’ in the ad area and seeing if it will zoom out? One of the problems I had was the content would be some weird crazy zoom.

  • http://profiles.google.com/vladsokol76 Владислав Соколов

    it’s only for as2.0!

    What can i do with as3.0? He has’t flash.media.StageWebView.

  • Slic33

    Hi Terry, thanks for the reply. I have tried clicking to zoom all the way in and out, still no luck. I even made the StageWebView the size of the stage to see if something was hiding, still nothing. It’s almost like the javascript portion of the html is working in the browser, but not in the StageWebView. Has admob changed their javascript since you wrote this I wonder?

  • http://www.terrypaton.com Terry Paton

    Actually I’ve now had my admob account cancelled apparently due to ‘click fraud’. This doesn’t help your problem though I don’t think.

    I did a little research and found other people are encountering the same issue – Admob are viewing the ads as potential for click fraud so they seem to be cancelling as few accounts. (don’t have the page handy sorry).

    Very sad situation.

  • Slic33

    Wow, that’s a downer. I wonder if that’s because all of your app’s impressions are funneling through your domain. So to admob, it looks like the same source is constantly requesting ads?? I’m tempted to ditch trying to get this to work on admob and moving to smaato. Any experience with Smaato? I’ve heard they may cancel your account if you don’t hit something like 1 million impressions. I didn’t realize putting ad support on an air app was next to impossible!

  • nick

    thank you for posting this, works perfect!

  • http://twitter.com/CarrSolutions Carr Solutions

    I have both AdMob and Smaato working in Adobe AIR. Please contact me at adsforAIR@carrsolutions.com if you are interested. Had the first demo of these on Android market late last year. 

  • Nevetx

    2.0?
    this is 3.0

  • Tim Martins

    I heard that use this way to add adMob. Your admob account will be suspended for using it. My flash games on android wants to use it. So, is it true??

  • Tim Joyce

    Thanks a lot Terry, works perfectly.

  • Hema

    Thanks for posting this. It works fine for me on desktop. I am able to receive live ads. But when I deploy it to device, it shows only the default ad

  • http://twitter.com/davecates davecates

    Does anyone’s ad rotate properly? Mine just hangs on the first ad…

  • http://twitter.com/davecates davecates

    have you changed the test field to ‘false’?

  • Anonymous

    It shows a small ad on tablet but the webview scales much larger. What is worse is that in android honeycomb, clicking on an ad fails to load, just gives error in the webview. On pre-3.0 android, it launches correctly. I wish there was tighter ad integration at least on the android side where people dont seem to buy apps.

    Anyone have any solutions?

  • http://pulse.yahoo.com/_RY5AKF6UBMMVD6X3OZK6DQSRSY Vikram J

    After a lot of trouble (account canned on ADMOB ) and
    research, I have gotten Ads to work in all my Android Apps. This will work on a
    lot of AD networks, but most will ban you click fraud. Only one network allows
    this method and they provide support for it too.

     

    I have over 100 games apps. with this method implemented and
    working. Here is a link to one of them for you to see how it will look in game.
    I am using multiple ads in this to force the user to click and make me some
    money: https://market.android.com/details?id=air.GraffitiCityMarketFree&feature=search_result

     

    Does
    LeadBolt offer HTML integration for banner ads?

    LeadBolt
    does allow banner ads to be integrated into your app using HTML, rather than
    using our SDK. To create a HTML banner ad after adding an app to the LeadBolt
    portal, simply click “Add Ad” and select “App Banner (HTML)” from the drop down
    box. The HTML snippet can then be added directly into your app’s HTML
    framework.

    So far my eCPM is $6.15

     

    I have created
    this guide to show my appreciation:

     

    Publisher Code:

     

    STEP I:

    Get an Account: http://leadboltapps.com/web/publishers/signup.php?ref=10022842

    STEP II:

    Click on the “APPS” tab and “Create New APP” to create an
    AD. Remember to change content unlocker to HTML Banner. While in the process.

    STEP III:

    Get the HTML AD Code
    and keep it safe. That is all we need from the site. How simple was that?

     

    AD HTML FILE:

     

    Create an HTML File and Load it to your site. Remember to replace
    your HTML Code from above step with where I have put: ****ENTER HTML AD CODE HERE****

     

    Untitled Document

    body,td,th {

         color: #FFF;

    }

    body {

         background-color:
    #000;

         margin-left: 0px;

         margin-top: 0px;

         margin-right: 0px;

         margin-bottom: 0px;

         text-align: center;

         position: relative;

    }

     

     

    ****ENTER HTML AD CODE HERE****

     

    Action Script Code:

     

    STEP I:

    Credit: I found this on another site and would like to give
    credit to the author of pixelpaton.com

    The only change you need to make is to enter your website
    html url where you have placed the AD HTML FILE in the space where I have put :
    “****ENTER COMPLETE HTML URL
    HERE****”. Where ever you want the AD, place the following code:

     

    // 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 = “****ENTER COMPLETE HTML URL HERE****”;

    //

     

     

                    {

                    //
    check that _stageWebView doersn’t exist

                    if (!
    _stageWebView) {

                                    _stageWebView
    = new StageWebView () ;

                                    //
    set the size of the html ‘window’

                                    _stageWebView.viewPort
    = new Rectangle(0,0, 800, 100);

                                    //
    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

                   

                    }

    }

     

    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) {

                                    //
    destroy the ad as the user has kindly clicked on my ad

                                    destroyAd(null);

                                    //
    Launch a normal browser window with the captured  URL;

                                    navigateToURL(
    new URLRequest( event.location ) );

                    }

    }

    // setup button listeners

     

     

    Hope this works and helps you. If you have questions, let me
    know. Enjoy.

  • Kingoftheworld_87

    Iv been playing with this for a while now and im not really getting anywhere, the ad isnt displaying properly, also how do you make the ad display instantly (without pressing any buttons?)

  • Anonymous

    This is not working for me. No ads are displaying and I’m not sure what I am doing incorrectly. Here is my HTML page with the AdMob code. Does anyone know what I am doing wrong?
    http://www.wordzigzag.com/admob.html

  • http://blog.bellinsky.com Vadim BELLinSKY

    Use LocationChangeEvent.LOCATION_CHANGING instead of LocationChangeEvent.LOCATION_CHANGE

  • Mikhey

    >> …problem of ads no showing up was in fact due to there being no ads to show!

    You can add to html file AdSense сode (not AdMob), for example mediabanner 468х60.
    It will be always shown, as rule

  • Invaderzimtwo

    I am getting Error #2044: Unhandled ErrorEvent:. text=Load error.
    I don’t know why, can anyone help me with this?

  • BoBoGames

    Everything is working great so far, I thank you for that. However, I’m a newbie to all this, can someone explain to me what i do with the .html file you need to create?

    Thanks in advance for any help

  • Raj859

    Hi,Im using StageWebView to display a webpage on my Android Application…..Can any one please help me , how to change the Default WHITE Background color of the StageWebView….
    Thanks,
    Rajkumar

  • Nikhil Mahirrao

    I am putting my html file with swf and I got this error :(

    ReferenceError: Can’t find variable: console
     at http://mmv.admob.com/static/iphone/ad.js?1320103418 : 1
     at http://mmv.admob.com/static/iphone/ad.js?1320103418 : 1

  • Ttytyty

    hello great post!  is it possible to not host the html page on a remote server, but include it with the apk file when I publish from flash since it is all client side javascript code that will work with android? I tried techniques from google where people create a temporary file then move it over but it doesnt work on actual devices.

  • http://www.terrypaton.com Terry Paton

    Sorry never done anything quite like that. Unfortunately I can longer use admob in my apps as they shutdown my account. No explanation why :(

  • http://twitter.com/lucas_tejero T

    hi terry your blog its very usefull for me,but i have a problem and i cant fix it,when i place de html with admob in my page to see adverts it dont show nothing,thank you from argentina

  • Ivo Gregurec

    Any progress with that issue? I just stucked there.

  • BoneStamp

    From reading a number of these posts, it seems that AdMob doesn’t support HTML ads anymore. Other people have indicated that they were accused of click fraud when serving ads in this way since all of the requests are coming from the same server. Obviously we know that it’s not fraud, but they apparently don’t.

    LeadBolt does continue to support html ads loaded through stagewebview for those who are interested.

  • Thanks

    thanks

  • http://www.facebook.com/TheThornZ Aaron Thorns

    Smart phone web has been taken down.

  • http://www.terrypaton.com Terry Paton

    Hi ya, yeah sorry I am no longer developing with AIR for my content, this post was written quite a while ago now (2011?). Unfortunately I won’t be sorting out any problems with it.

  • LeXu

    thx a lot for this. do you have any ideea if admob revenue is different for bigger ads or it is the same for all the sizes?thx

  • Mike Monti

    This is a nice piece of work!

    However i would like to suggest you an additional entry:
    https://github.com/Code-Alchemy/AdMobAne

    This is an AdMob ANE extension for either iOS and Android.
    The packages are also available specifically for the platform. an it is completely free.

    I did look a lot around for an Admob Extension which can cover all AdMob functionality and i never found one!
    Also the one of your links are very limited, and all seems base in old library and not maintained which are refused automatically from either Apple Store and Google (from August 2014).

    The extension is always fully maintained and constantly base on the latest AdMob SDK for iOS and Android!

    I strongly suggest it to anyone who need a reliable AdMob ANE extension without loosing time!