Monday, April 20, 2015

How-To use AdMob Interstitial Ads with Delphi XE7-XE8

Hi guys,
as you know by using the Delphi Android JNI you can access to Native features provided by Android SDK. The RAD Studio installation includes also Google Mobile ADS library (Androidapi.JNI.AdMob unit), as built-in java library for Android.
So by using this unit we can use the new Interstitials Ads provided by AdMob.
First of all rember to set to true the AdMob Service ( Project -> Entitlement List -> AdMob Service )



Let's start with the code.
Create an instance of TJInterstitialAd, wich is present in Androidapi.JNI.AdMob.
  
    FInterstitial := TJInterstitialAd.JavaClass.init(MainActivity);
    FInterstitial.setAdUnitId(StringToJString('Your-Publisher-ID'));

For example you can put the previous code in the FormCreate event. Then you have to use this code to display an Interstitial Ad (on button-click event in my demo):

var
  LADRequestBuilder: JAdRequest_Builder;
  LadRequest: JAdRequest;
begin
  LADRequestBuilder := TJAdRequest_Builder.Create;
  LADRequestBuilder.addTestDevice(MainActivity.getDeviceID);
  LadRequest := LADRequestBuilder.build();
  LAdViewListener := TMyAdViewListener.Create(FInterStitial);
  CallInUIThread(
    procedure
    begin
      FInterStitial.setAdListener(TJAdListenerAdapter.JavaClass.init
        (LAdViewListener));
      FInterStitial.loadAd(LadRequest);
    end);
end;

I used the TJAdRequest_Builder to create a request and set my device like a test device (see AdMob guidelines).
I also created a custom AdViewListener to intercept the interstitial events:
  • onAdClosed;
  • onAdFailedToLoad(errorCode: Integer);
  • onAdLeftApplication;
  • onAdOpened;
  • onAdLoaded;
TJAdListenerAdapter adapts my Listener class to Interstitial AdListener, this because I created a custom class to support interstitial events and show effectively the Ad when it was loaded.

TMyAdViewListener = class(TJavaLocal, JIAdListener)
  private
    FAD: JInterstitialAd;
  public
    constructor Create(AAD: JInterstitialAd);
    procedure onAdClosed; cdecl;
    procedure onAdFailedToLoad(errorCode: Integer); cdecl;
    procedure onAdLeftApplication; cdecl;
    procedure onAdOpened; cdecl;
    procedure onAdLoaded; cdecl;
  end;

procedure TMyAdViewListener.onAdLoaded;
begin
  FAD.show;
end;

Here the screenshot of interstitial on my phone:


This code should works also on AppMethod.
You can find the demo in my GitHub repository.

34 comments :

  1. Replies
    1. For this tutorial I've used only the existing bridge files available for Delphi. You can find the same units in include\android\rtl (path for C++) and use them in the same way I did.

      Delete
  2. Great tutorial, is there a link to download the demo project? (Delphi XE8)

    ReplyDelete
    Replies
    1. I have added the demo in my GitHub repository https://github.com/spinettaro/DelphiDemos

      Delete
  3. How to use without test mode.
    I could not do it. Thanks

    ReplyDelete
  4. admob dont run on delphi 10 seatlle

    ReplyDelete
  5. I've been following this tutorial: Brilliant! Thanks!
    But I have one problem: Ads are shown in test mode... How to set test mode OFF?

    ReplyDelete
    Replies
    1. Hi! Try to remove this line
      LADRequestBuilder.addTestDevice(MainActivity.getDeviceID);

      Delete
  6. Hi!

    Great!!!! It works!

    (I feel I should have found this myself in your code... :-S)

    Really THANKS!!!

    THANKS! THANKS!



    ReplyDelete
    Replies
    1. You're welcome! I really like your enthusiasm!! :)

      Delete
  7. Hi there I am done with a game for android and need to add admob advertising.
    I am using c++, I having trouble with it. Banners and interstital doesnt seem to work.
    Simple banner is not even working and i marked allow internet and admob to yes.

    Please help.

    Thanks.

    ReplyDelete
    Replies
    1. Hi! What about Access Network State permission? It should be checked if I remember correctly...

      Delete
    2. This comment has been removed by the author.

      Delete
    3. Hi daniele, also my app crashes whenever it returns from opening an external link like email, go to url or interstial ad. i disabled timer and stopped mediaplayer too, but still have the problem

      Delete
    4. Also have you done rewarded videos?

      Delete
    5. Thanks, this was solved by editing the android manifest file and adding this :

      Delete
  8. This comment has been removed by the author.

    ReplyDelete
  9. Hi, I want to award the user for watching a video with gems in my game, do I use Interstitial or rewarded video in admob? If It is rewarded video, how do i implement so

    ReplyDelete
    Replies
    1. Hi! Yes you have to use Rewarded Video... I need to understand how it works and convert it to Delphi. I'll work on it, stay tuned!

      Delete
  10. Thanks Daniele, I really apprecite it. As that will help me alot as this is the last main thing that is delaying my launch. Don't mean to sound like a nag, but do you have an approximation on how long this will take as you seem to be the only one worldwide that is clued up on how to do this.

    ReplyDelete
  11. Hi Danielle Spinetti,

    I found this to work with on ffg link. Would this help?

    https://github.com/googleads/googleads-mobile-android-mediation/blob/e665019b3077f5456676677841531f45a6cae377/Example/adapter/src/main/java/com/google/ads/mediation/sample/adapter/SampleMediationRewardedVideoEventForwarder.java

    ReplyDelete
  12. Hi Daniele Spinetti,

    I think this link should help more. I hope 1 of us can come with a solution on this. Thanks again

    https://github.com/googleads/googleads-mobile-android-examples/blob/master/admob/RewardedVideoExample/app/src/main/java/com/google/ads/rewardedvideoexample/MainActivity.java

    ReplyDelete
  13. I also noticed on admob for example, you set the reward amount eg 5, and what the reward is ("Text) eg gems. and on the implementation the function gets this from admob. Last link i posted is the ultimate help on this

    ReplyDelete
  14. have this so far :

    class MainActivity : public Activity, public RewardedVideoAdListener
    {
    private:
    //JAVA TO C++ CONVERTER TODO TASK: Native C++ does not allow initialization of static non-const/integral fields in their declarations:
    static const std::wstring AD_UNIT_ID = L"ca-app-pub-3940256099942544/5224354917";
    //JAVA TO C++ CONVERTER TODO TASK: Native C++ does not allow initialization of static non-const/integral fields in their declarations:
    static const std::wstring APP_ID = L"ca-app-pub-3940256099942544~3347511713";
    int mCoinCount = 0;
    TextView *mCoinCountText; //change to edit1
    RewardedVideoAd *mRewardedVideoAd;
    // Button *mShowVideoButton; //change to button
    public:
    virtual ~MainActivity()
    {
    delete mCoinCountText;
    delete mRewardedVideoAd;
    delete mShowVideoButton;
    }
    // };
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    protected:
    void onCreate(Bundle *savedInstanceState) override
    {
    __super::onCreate(savedInstanceState);
    setContentView(R::layout::activity_main);

    // Initialize the Mobile Ads SDK.
    MobileAds::initialize(this, APP_ID);

    mRewardedVideoAd = MobileAds::getRewardedVideoAdInstance(this);
    mRewardedVideoAd::setRewardedVideoAdListener(this);
    loadRewardedVideoAd();

    }


    private:
    void loadRewardedVideoAd()
    {
    if (!mRewardedVideoAd::isLoaded())
    {
    AdRequest::Builder tempVar();
    mRewardedVideoAd::loadAd(AD_UNIT_ID, (&tempVar)->build());
    }
    }

    void addCoins(int coins)
    { //here we implement the adding of gems
    mCoinCount = mCoinCount + coins; //change
    //mCoinCountText::setText(L"Coins: " + mCoinCount); //change
    mCoinCountText->Text=(L"Coins: " + mCoinCount);
    }

    void showRewardedVideo()
    {
    mShowVideoButton::setVisibility(View::INVISIBLE);
    if (mRewardedVideoAd::isLoaded())
    {
    mRewardedVideoAd::show();
    }
    }

    public:
    void onRewardedVideoAdLeftApplication() override
    {
    Toast::makeText(this, L"onRewardedVideoAdLeftApplication", Toast::LENGTH_SHORT).show();
    }

    void onRewardedVideoAdClosed() override
    {
    Toast::makeText(this, L"onRewardedVideoAdClosed", Toast::LENGTH_SHORT).show();
    // Preload the next video ad.
    loadRewardedVideoAd();
    }

    void onRewardedVideoAdFailedToLoad(int errorCode) override
    {
    Toast::makeText(this, L"onRewardedVideoAdFailedToLoad", Toast::LENGTH_SHORT).show();
    }

    void onRewardedVideoAdLoaded() override
    {
    Toast::makeText(this, L"onRewardedVideoAdLoaded", Toast::LENGTH_SHORT).show();
    }

    void onRewardedVideoAdOpened() override
    {
    Toast::makeText(this, L"onRewardedVideoAdOpened", Toast::LENGTH_SHORT).show();
    }

    void onRewarded(RewardItem *reward) override
    {
    Toast::makeText(this, std::wstring::format(L" onRewarded! currency: %s amount: %d", reward->getType(), reward->getAmount()), Toast::LENGTH_SHORT).show();
    addCoins(reward->getAmount());
    }

    void onRewardedVideoStarted() override
    {
    Toast::makeText(this, L"onRewardedVideoStarted", Toast::LENGTH_SHORT).show();
    }

    };

    ReplyDelete
  15. Hi Daniele,

    Any luck with the rewarded video, can it be done on embarcadero?
    Also My interstitial app crashes on some phones when closes. is there a way to restart app upon crash?

    ReplyDelete
  16. hi This code works very well. Thank you for sharing.
    But the device can be canceled with the back button. Do you have a solution to this already thank you very much.

    ReplyDelete
  17. Hi Daniele This code works very well. Thank you for sharing.
    But the device can be canceled with the back button. Do you have a solution to this already thank you very much.

    ReplyDelete
  18. Hi Daniele This code works very well. Thank you for sharing.
    But the device can be canceled with the back button. Do you have a solution to this already thank you very much.

    ReplyDelete
  19. How can I prevent the display from shutting down for 5-6 seconds? Does not this have knowledge?

    ReplyDelete
  20. hi, i have rewarded video, interstitial and banner ads done thru aerserv integration. It fairs much better than admob. and you can add ad network mediations to it like admob etc. The event handling is much easier too. Basically you install a plugin. and it adds the component to the tools.

    ReplyDelete
    Replies
    1. Is it possible to cancel the device back key on the right hand side?

      Delete
  21. I have done interstitial ads, videos, banner and rewarded video with aerserv. It works much better

    ReplyDelete
  22. Merhaba, ben uygulamayı çalıştırdım fakat sizin gibi geri tuş özelliğini kapatamadım. Videolar 15, 20, 30, 33 saniye gibi değişen sürelerde sonlanıyor. Bu arada siz bir çözüm bulabildiniz mi?
    teşekkürler

    ReplyDelete