Tutorial: Implementing AdMob

google-play-store
Share on Facebook1Share on Google+4Tweet about this on TwitterShare on LinkedIn1

For those who haven’t used ads before — in particular AdMob — let’s start at the beginning. To use AdMob, you must add a block of code to your build.settings file (see the recent tutorial if this topic is unfamiliar). This block goes into the plugins sub-table of the parent settings table:

Understanding the Corona ad system

At the basic level, including ads in your app involves these core factors:

  • Initializing the ad provider.
  • Showing an ad.
  • Hiding an ad.

AdMob, like the other ad providers, must have its service initialized within your code. For this to occur, you’ll need an “App ID” from AdMob. In specific AdMob terms, this is referred to as an Ad Unit ID and it’s a string that looks similar to this:

Going forward, this tutorial will use ca-app-pub-nnnnnnnnnnn/nnnnnnnn, but it’s your responsibility to substitute your Ad Unit ID whenever the tutorial calls for setting the AppID.

Most ad providers use one AppID per platform. This means that you’d have one AppID on iOS and another AppID on Android. Thus, at the point when you initialize your ad provider in code, you’d include some conditional logic to determine if the platform is Android or iOS and then provide the appropriate AppID. For example:

However, AdMob takes this one step further. In addition to having a unique ID per platform, you must also provide a unique ID per ad type. This is discussed in the next section.

Ad types

Most ad providers offer two types of ads and AdMob is no different in this respect:

  • Banners — ads which may appear somewhere within a scene of your app.
  • Interstitials — ads (typically fullscreen) which may appear between scenes in your app.

Most Corona developers want to use both types of ads, and AdMob supports this in the form of a unique Ad Unit ID for both ad types on each platform. This means that, for deployment to iOS and Android, you may have four IDs to manage. As such, you may want to consider this strategy:

Note that you should carefully consider the user’s experience when planning an advertising strategy. Everyone wants to make money from their apps, so showing both banners and interstitials may seem a logical approach. However, advertising can detract from the user experience and often you’ll have greater success with compelling content versus frequent ads.

Showing ads

For most ad providers, showing an ad can be done with simply the ad type and a table of parameters:

For instance, with iAds, you can simply show a banner ad by providing the ad type along with an x and y location on the screen:

Because of how AdMob abstracts its ad types, however, you have to change IDs based on the ad type. This is factored into the parameters table via an appID key:

Without this appID parameter, AdMob will be unable to match the Ad Unit ID of the requested type with the platform and the ad delivery will fail.

The “adListener” callback function

Corona’s ads library supports a function which listens for certain ad-related events. In general, this function is called either when an ad loads successfully or when it fails to load.

Note the “load” terminology here. If you consider how ads work, they must first be fetched from the ad server (“loaded”) and then displayed (“shown”) to the user. Corona has consolidated this to a single function in most cases, so typically ads.show() performs both actions. This is an important designation that will be covered below.

Let’s look at a typical adListener() function for AdMob:

With this listener function, you can watch the device’s console log and see what’s happening with your ads code. If you’re not familiar with viewing the device’s console log, the tutorial on basic debugging may be useful. Note that almost all ad services require that you test on an actual physical device.

Banner ads

Banner ads are short rectangles that usually span the width of a phone — 320×50 is a fairly typical size. These work best when drawn at the top or bottom of the screen. You’re only allowed to show one banner at a time, and changing of ads is controlled on the server side at a range of 30-60 seconds.

AdMob provides several “formats” for banner ads:

  • Text-Only
  • Static Graphic
  • Animated

The AdMob portal allows you to choose either text or graphic, but it doesn’t allow you to request animated in specific. Animated banners have a higher eCPM value (more value to you), but they’re resource-intensive and can impact the app frame rate when shown.

Google strongly advises that you do not show banners at times where your CPU time is at a premium, for example, during the main gameplay state of a fast-paced game. In any case, users will likely ignore ads during intensive gameplay, so these ads provide minimal value to the advertiser. Additionally, these may hinder the overall experience so much that users outright uninstall the app. In almost every instance, it’s better to show banner ads when the user is more likely to tap on them, for example, during level select screens, on the app’s main menu, etc.

Handling banner height

AdMob banner ads can also have a variable height which can impact your user interface (UI). You could just leave space for the maximum banner height, but if you want your UI to fit snuggly alongside the advertising, you’ll need to know the ad’s height.

Corona allows you to gather this height, but only after the ad has successfully loaded. More specifically, if the adListener() function is called and indicates that the ad is successfully loaded, you can call the ads.height() function to determine the height of the ad and adjust your UI accordingly.

Positioning banners

Banner ads are positioned around their top and left corner point. Thus { x=0, y=0 } in the parameters table indicate that the top-left corner of the ad should be in the top-left corner of the screen content area. If you want to show an ad at the top of the screen, this isn’t an issue — just position it at x=0, y=0. However, positioning a banner at the bottom of the screen is theoretically more tricky, since you don’t know the height of the ad until after it loads, and thus you can’t set a specific y offset from the bottom of the screen.

Fortunately, you can utilize a trick to position it perfectly along the bottom. Because advertisers don’t want you to show ads partially off screen, the ad library itself ensures that the ad is fully shown on screen — just intentionally set the ad’s y position offscreen and Corona will automatically bring it back on the screen:

Cycling banner ads

In the AdMob portal, banner ads can be set to cycle at a time increment between 30 and 60 seconds. There’s no function in Corona to request an ad cycle, and using ads.hide() followed by ads.show() will not “force” an ad cycle.

Interstitial ads

Interstitial ads are designed to show between scenes. They’re typically full screen and they should have a method to close the ad (typically a small × in the corner). Any other touches should send the user to the ad’s destination site. Some interstitial ads are even animated and may include interactivity.

Like banners, you can use ads.show() to show interstitial ads:

Remember that if you’re mixing both banner and interstitial ads, you must also include the appId of the ad type in the parameters table:

Note that you don’t need to provide an x and y position for interstitial ads since they occupy the whole screen.

Pre-loading interstitials

Because these rich ads can take time to download (perhaps several seconds), loading an interstitial ad “on demand” using ads.show() may be too slow for your game flow. Fortunately, the AdMob plugin supports pre-loading of interstitial ads, allowing you to load the next ad in advance of when you wish to show it.

To pre-load an interstitial ad, call the ads.load() API. The function takes all the same parameters as ads.show(), but in this case, you’re separating the ad process into two parts — fetching the ad (ads.load()) and displaying the ad (ads.show()).

In respect to interstitial ads, the delay comes from the loading portion, while showing the ad happens almost instantaneously. In terms of handling events, an event phase of "loaded" is triggered when you call ads.load(), but if you just call ads.show(), you won’t get any events until the ad is closed. The reason for this behavior is that if you just call ads.show() and you don’t get an ad, you’ll get an event where the phase is irrelevant. In this case, you can check the .isError value and, if it’s true, you can attempt to fetch an ad from another service. For example:

Since your callback function will trigger when the ad is loaded, you could theoretically set a flag and later check the flag to determine if the ad is ready to show. However, Corona provides an additional convenience function called ads.isLoaded(), so when you’re ready to show the ad, simply call:

Conclusion

Hopefully, this tutorial outlines how you can successfully implement AdMob in your apps.


Share on Facebook1Share on Google+4Tweet about this on TwitterShare on LinkedIn1
Rob Miracle

Rob Miracle creates mobile apps for his own enjoyment and the amusement of others. He serves the Corona Community in the forums, on the blog, and at local events.

This entry has 64 replies

  1. David Grant says:

    I see you mention the animated banners but you don’t show any code on how to actually call them. I can’t find it in any of the docs or anything can you give an example of use? Also I like the trick of setting the Y off the screen and corona will load it on the bottom I will be adopting that for sure.

    • Rob Miracle says:

      You have no control over animated vs. non-animated. Google sends you what they want. You can get text only though.

      Rob

      • David Grant says:

        Okay that makes sense. I reread the article and I understand now. I thought you were saying that the admob site doesn’t allow you to request an animated banner but corona will type thing.

  2. Mark says:

    What should the appID be if we have both banner and interstitial? Or do we need to init twice?

    ads.init( adProvider, appID, adListener )

    • Rob Miracle says:

      You will have two AppID’s, one for the Banner Ad, one for the Interstitial. It really doesn’t matter which one you init with since you have to provide the AppID on the actual ad.show() or ad.load() call.

      Rob

  3. Mark says:

    Also unable to get interstitial ads on iOS. Android is working fine. Anyone with similar issue?

  4. deniz says:

    admob v2 plugin seems not working correctly if you are also using facebook plugin. it crashed on a wide portion of my android test devices regularly. no problem on ios doh.

    • David says:

      deniz – in case you haven’t already, can you post about this in the forum? It will be much easier to take the report there and comment on it…

  5. John says:

    ROB – THANK YOU!
    I’ve been all over the forum tweaking my implementation and this write up is exactly what the community needed. Also, with the addition of the “shown” phase we finally have a useful callback.

    I will say your last statement is a bit misleading. I’m a new basic user and have consumed admob v2 already, I’m hoping you all intend to release the next public version relatively soon… ie. before the 1st (it’s been more than 2-3 months since the last public release). To that point, you’re not giving your users a lot of time to handle this which is disappointing. Making app updates, performing device testing, regression testing, and app store submissions in a short time frame hurts, Rob, it hurts.

  6. I’m using Admob v2 with daily build 2359. When I build an app and install it on an iOS device I get the following warning (using Xcode to see the console output).

    : Google Mobile Ads SDK: You are currently using 6.8.0 of the SDK. A new version, 6.9.2, is available at http://goo.gl/Zc0BYt . Please consider updating your SDK to get the latest features and bug fixes

    My banner ads are showing as expected and I can see from my Admob account that my usage is being reported.

    Just wondering what this warning means. Do I need to do something or will the plug-in be updated?

    • Rob Miracle says:

      The plugin will be updated automatically. Engineering is looking into it.

  7. kevin says:

    supper job works for me 😀

  8. kevin says:

    looks like you are working on the plugin right now as im getting this error:

    A device build error occurred on the server.

    BuildID: 53c7faaf31a52
    Error: Get plugin failed.
    Publisher: com.coronalabs
    Plugin: plugin.google.play.services

    • Rob Miracle says:

      Are you still having issues with this? If so, please start a forum thread about it so we can support you there. Posting code here doens’t work very well.

      Rob

      • brandon says:

        Hello i am confused on what to do to put a banner ad in my app.

  9. Lerg says:

    Integrated both Admob and Adbuddiz in my 2048 Hex game (on Android at the moment).
    Thank you!

  10. Francisco says:

    My game shows a banner ad from admob when there is a game over. Since the user click “Play again” fast, the ad is too slow to show up. Maybe it is just me, but now the ad it is even slower than before to show up. 🙁

    What I am doing is a ads.show() when there is a game over, and a ads.hide() when the user press “Play again”. Am I doing it right?

    Here you have the game to check it out for yourself:

    https://play.google.com/store/apps/details?id=com.dosdrebel.heavydevil

    • Rob Miracle says:

      You could disable the play again button until after you get a call back from the ad listener saying it showed the ad.

      Rob

      • Francisco says:

        I prefer not to get people mad waiting an ad to show… :-S

        If I want to hide an ad just for a couple of seconds and show it again, should I do ads.hide() and then ads.show() or it is another faster way?

        • Rob Miracle says:

          Those are your only controls.

          Rob

          • Francisco says:

            Ok, that is cool then.

            Thank you Rob for your help! 🙂

    • brandon says:

      Hello what code did you use to get the ads ? and how did you get the ad from admob because im having a really hard time completing these .

  11. Alan says:

    Looking forward to news on the next public release… why is it being kept under such tight wraps? We are all anxiously awaiting!

  12. Rob Miracle says:

    It’s a complex answer. There are too many variables that affect when we put out a public release. Desired features, certain bugs, timing of OS releases and Apple/Google mandated changes, etc. all impact our release schedule. The daily builds have to be solid enough and have not broken something that was working in the previous public build (regression bugs). We don’t like giving dates, until we know we can hit them and when there are too many variables, its hard to know.

  13. Felix says:

    This means, that it is no more possible to use admob with a basic subscription after the first of August until the next puplic build is out?

    Please tell me I understood something wrong.

    Felix

    • David says:

      This is correct, but we are planning on putting out a new public release as soon as possible.

      • Felix says:

        Well.
        ok, thank you for the answer.
        Do you know what will happen with my game that is out now with admob v1 after August 1st, if I do not remove admob?
        I mean will the game break when an ad is loaded or will there simply be no ad?

        Felix

        • Rob Miracle says:

          We believe that Admob V1 based apps will continue to serve ads for some time. You won’t be able to update a V1 app unless you switch to V2, nor will you be able to upload a new V1 app.

          Rob

          • Felix says:

            ok, thank you for the response.
            lets hope the best 🙂

          • Harry Tran says:

            So for those on basic subscription it’s best to not make any updates until the next build is released is that correct, otherwise Apple will reject the file?

          • Rob Miracle says:

            This change does not affect AdMob on Apple, only on Google Play.

  14. Matheus says:

    The public release is going to be available before 1st August, right?

    • Rob Miracle says:

      We are working to get a new public build out and we are aware of the date.

  15. Radim says:

    I realized that if I use AdMob and Vungle then ads.load() will crash the app if Vungle is initialized. I always have to use ads:setCurrentProvider( “admob” ) before calling ads.load()

  16. David says:

    Nice tutorial – thanks!

    I’m trying to use an Interstitial ad when the app first starts (this works fine) and switch to a banner app after the user closes the interstitial. Previously I only had banner ads so I know my IDs are correct but I can’t get the banner to work after the interstitial was displayed.

    I even tried this:

    appID = bannerAppID;
    ads.init( adProvider, appID, adListener );
    ads.show( “banner”, { x=0, y=0, appID } );

    But this doesn’t work either. Am I suppose to somehow remove the first call to ads.init?

    appID = interstitialAppID;
    ads.init( adProvider, appID, adListener );

    • Rob Miracle says:

      If you only are using AdMob, then you should only call init once. Switching between banners and interstiital’s is done via the ads.show() API call. If you use multiple ad providers, you will need one ads.init() for each provider.

      Rob

      • David says:

        Here’s what’s going on:

        appID = interstitialAppID;
        ads.init( adProvider, appID, adListener ); — init is first called with the interstitialAppID

        — check if online, if so then

        ads.show( “interstitial”, { appID=interstitialAppID } ); — this does show the interstitial ad

        — once closed, the user clicks a button to start and the following is executed:

        ads.show( “banner”, { x=0, y=0, appID=bannerAppID } );

        — No banner is ever displayed 🙁

        • David says:

          Only using AdMob.

        • Rob Miracle says:

          Please post this in the forums. Blog comments doesn’t handle code very well and you are limiting the number of people who can help you.

          Rob

  17. John says:

    I am getting this response in my app:

    2014-09-04 12:22:26.890 AppName[14189:90b] Google Mobile Ads SDK: You are currently using 6.8.0 of the SDK. A new version, 6.11.1, is available at http://goo.gl/Zc0BYt . Please consider updating your SDK to get the latest features and bug fixes

    Will you guys be updating to the new SDK soon?

    • Rob Miracle says:

      We will update at some point, usually when the changes warrant it. I’ll remind engineering, but unless there is some serious bugs being fixed or new features, we can’t just go be rebuilding these plugins every time there is an update. Google changes things and it could break many users.

      Rob

      • Bryan Silva says:

        Can you please tell me why I can’t show banner ads?

        This is my code, is anything wrong?

        settings =
        {
        plugins =
        {
        [“plugin.google.play.services”] =
        {
        pub-8347067101481503 = “com.coronalabs”
        },
        },
        }

        android =
        {
        usesPermissions =
        {
        “android.permission.INTERNET”,
        “android.permission.ACCESS_NETWORK_STATE”,
        },
        },

        local ads = require( “ads” )
        local bannerAppID = “ca-app-pub-8347067101481503/4080572917” –for your iOS banner
        if ( system.getInfo( “platformName” ) == “Android” ) then
        bannerAppID = “ca-app-pub-8347067101481503/2335507715” –for your Android banner
        end

        local adProvider = “admob”
        local function adListener( event )
        –(more on this later)
        end

        ads.show( adtype, table_of_parameters )

        ads.show( “banner”, { x=0, y=0, appId=bannerAppID } )

        local function adListener( event )
        — The ‘event’ table includes:
        — event.name: string value of “adsRequest”
        — event.response: message from the ad provider about the status of this request
        — event.phase: string value of “loaded”, “shown”, or “refresh”
        — event.type: string value of “banner” or “interstitial”
        — event.isError: boolean true or false

        local msg = event.response
        — Quick debug message regarding the response from the library
        print( “Message from the ads library: “, msg )

        if ( event.isError ) then
        print( “Error, no ad received”, msg )
        else
        print( “Ah ha! Got one!” )
        end
        end

        ads.init( adProvider, appID, adListener )

        ads.show( “banner”, { x=0, y=100000 } )

        • Rob Miracle says:

          This in your build settings is incorrect: pub-8347067101481503 = “com.coronalabs”
          It should be: publisherId = “com.coronalabs”

  18. GregH says:

    Thanks for the tutorial! What’s the recommendation for testing? I note in the Google docs they refer to using “test ads”? ( https://developers.google.com/mobile-ads-sdk/docs/admob/android/banner#test_ads ):

    “You should use test ads during development to avoid generating false impressions. Additionally, you can always count on a test ad being available. Set up test ads by passing your hashed Device ID to AdRequest.Builder.addTestDevice: AdRequest request = new AdRequest.Builder() … ”

    I assume Corona doesn’t support this? Not sure what the negative is to testing using the final setup, but before you’ve deployed live to Apple (i.e. just when you’re building then putting on your own device).

  19. Position and height-width set :
    ads.show(“banner”, { x=100, y=display.contentHeight-30,width=display.contentWidth-200,height=40 })

  20. Rafael says:

    how do I know if the user clicked the ad?

    • Rob Miracle says:

      For banners, you won’t know. Your app will suspend, but you won’t know why it suspended. For Interstitial’s there will be a “shown” event that indicates that the user closed the ad, but you won’t know if they closed it or clicked through.

  21. Nate says:

    Hi Rob, great article. One error I found was a misspelling of “interstitial” under Ad Types (“interstitalAppID”).

    Which makes the call, ads.show( “interstitial”, { appId=interstitialAppID}) bring up the wrong appID.

  22. vivek says:

    Hey all!!! I m new to corona development and want to publish ads in my android app.But tutorials here are not worth too much help!!can sm1 please upload or send me a link to integrate banner ads using admob on corona applications!!!!!!help will be highly obliged!!!!! I am complete beginner and have developed an android app!help neded asap!!!!:)

  23. Payton says:

    If I’m using composer and switching to the scene that I have dedicated to showing my interstitial ads… how would I go about preloading it?

    I’ve tried ads.load(“interstitial”) in previous scenes… but if… and that’s a big IF it shows the ad… it’s after at least 2 minutes. And that’s on wifi. I really need the help… for my sanity.

  24. Rob Miracle says:

    You should not be having that kind of latency. You should be getting ads in a matter of seconds. What you could be describing is a low fill rate. If you’re not using test ads, you will get very few live ads. Your app gets live ads based on how popular it is. The more popular your app, the more likely your inventory will be filled.

    Rob

  25. David says:

    Why do you not update https://docs.coronalabs.com/plugin/ads-admob/index.html ? I just wasted half an hour trying to figure out what was wrong.

  26. Danilo says:

    adMob works with CORONA FREE?

    • Rob Miracle says:

      Yes.

  27. Vu Phan says:

    Hi

    When I add banner and interstitial, it crash and show message “Could not load provider admob due to following reason module ‘CoronaProvider.ads.admob’ not found…”

    I using new corona version (2731). I tried with anothor version such as 2710 but it not working.

    Please help me to solve this problem

    • Rob Miracle says:

      I’m confused. If you followed the tutorial, it has you load a plugin called plugin.google.play.services instead of plugin.ads.admob or something like that. The error you are getting is because you’re using Version 1 of the plugin which Google killed off well over a year ago. Change that line in your build.settings to load the plugin: plugin.google.play.services and you should be good to go.

      • Vu Phan says:

        Hi Rob

        I currently using plugin.google.play.services. This is content in my build.setting file:
        settings =
        {
        orientation =
        {
        default = “portrait”,
        supported = { “portrait”},
        },
        iphone =
        {
        plist =
        {
        UIPrerenderedIcon = true,
        },
        },
        android =
        {
        usesPermissions =
        {
        “android.permission.INTERNET”,
        “android.permission.ACCESS_NETWORK_STATE”,
        },
        },
        plugins =
        {
        [“plugin.google.play.services”] =
        {
        publisherId = “com.coronalabs”
        },
        },
        }

        * in “main.lua” I add an interstitial Banner with code:
        local ads = require( “ads” )
        local interstitialAppID = “ca-app-pub-1679022124514237/5808556504”
        local adProvider = “admob”

        local function adListener( event )
        if ( event.isError ) then
        print( “Error huhu” )
        elseif ( event.phase == “loaded” ) then
        print( “loaded hehe” )
        elseif ( event.phase == “shown” ) then
        print( “shown haha” )
        end
        end

        ads.init( adProvider, interstitialAppID, adListener )

        if ( ads.isLoaded(“interstitial”) ) then
        ads.show(“interstitial”)
        end

        Could you help me? May be I missing some thing?

        Thanks!

        • Rob Miracle says:

          Can you ask this in the forums? Blog post comments do not handle posting code very well. You will get a better response there than here.

          Rob

          • Vu Phan says:

            Ok Rob

        • Vu Phan says:

          – when I use version build 2329 it is not crash but my app show black screens and Game is stuck
          – When I use newest version build 2810 It still crash.

          Br,

  28. KIrby says:

    Is there any plans for updating the versions for admobs SDK? specifically to accommodate mediation?

    • Rob Miracle says:

      Its on our list of possible plugins to work on, but at the moment, our plate is full of other higher priority plugins and projects.

Leave a reply

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">