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.

20 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
  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. 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
  11. 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
  12. 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
  13. 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