Admob Rewarded Ads?

SLotman

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jul 3, 2017
Messages
239
Is this supported in Cerberus-X? I once did a module for it for Monkey-X, but it probably doesn't work anymore since Google is deprecating a ton of stuff :(
 

MikeHart

Administrator
CX Code Contributor
3rd Party Module Dev
3rd Party Target Dev
3rd Party Tool Dev
Joined
Jun 19, 2017
Messages
3,504
I don't think so
 

SLotman

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jul 3, 2017
Messages
239
Well, poop. Guess I'll have to figure it out once more, or migrate one project to Unity... something I'd really rather not do :p
 

Wingnut

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,284
I wish you could use ads in Cerberus easier, here's a fresh implementation of Rewarded ads in BASIC


 

SLotman

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jul 3, 2017
Messages
239
Well, its not that hard to use it when dealing with Interstitials or common banners. This is the code I use to show a banner on the screen bottom:

Code:
#If TARGET="android" Or TARGET="ios"
    Import brl.admob
#End

Function hideAd()
#If TARGET="android" Or TARGET="ios"
    Admob.GetAdmob().HideAdView()
#End
End Function

Function showAd()
#If TARGET="android" Or TARGET="ios"    
    Admob.GetAdmob().ShowAdView(2,5)
#End        
End Function

Not that difficult, right? ;)
 

SLotman

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jul 3, 2017
Messages
239
I think I did it!

Code:
D/[Cerberus](11855): Google Mobile Ads SDK
D/[Cerberus](11855): BBAdmobRewarded MobileAds.initialize
D/[Cerberus](11855): BBAdmobRewarded startAd()
E/[Cerberus](11855): BBAdmobRewarded run() -> _rewardedAd = null
D/[Cerberus](11855): BBAdmobRewarded adRequest
D/[Cerberus](11855): BBAdmobRewarded onAdLoaded
I/[Cerberus](11855): Showing rewarded ad...
D/[Cerberus](11855): BBAdmobRewarded ShowAdViewRewarded() -> loaded = true
D/[Cerberus](11855): BBAdmobRewarded run() -> _rewardedAd.show
D/[Cerberus](11855): BBAdmobRewarded FullScreenContentCallback -> The ad was shown.
D/[Cerberus](11855): BBAdmobRewarded adRequest
D/[Cerberus](11855): BBAdmobRewarded onAdLoaded
D/[Cerberus](11855): The user earned the reward.
D/[Cerberus](11855): BBAdmobRewarded FullScreenContentCallback -> The ad was dismissed.

Ad shows, and I get the log that the reward was earned. The thing is that I have no clue how to send this message back into Cerberus, along with the 'ammount' earned and 'type' of reward.

Had to add this to the manifest, right before ${ANDROID_MANIFEST_ACTIVITY}, otherwise the app would crash:
Code:
    <meta-data
        android:name="com.google.android.gms.ads.APPLICATION_ID"
        android:value="real_app_id_generated_by_admob_here"/>

Also on build.gradle I've replaced
Code:
maven {
            url "https://maven.google.com"
        }
with:
Code:
mavenCentral()

Don't know if that is actually necessary or not. Don't know what will happen if an ad fail to load.

I couldn't test also what happens if you close the ad before earning the reward - no matter how much I clicked on the [x] the test ad wouldn't go away before the countdown ended :p

But... at least its something :)

rewads.png
 

MikeHart

Administrator
CX Code Contributor
3rd Party Module Dev
3rd Party Target Dev
3rd Party Tool Dev
Joined
Jun 19, 2017
Messages
3,504
Cool, so no need to port it to Unity. Glad you got it working
 

SLotman

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jul 3, 2017
Messages
239
Can you guys help me test it out?

Here is the code I've made:

rewarded_ads.cxs
Code:
#Rem
    SETUP NEEDED:

    (1) Open [project build]\android\gradletemplate\app\src\main\AndroidManifest.xml and add
    just before ${ANDROID_MANIFEST_APPLICATION}:

    <meta-data
        android:name="com.google.android.gms.ads.APPLICATION_ID"
        android:value="real_app_id_generated_by_admob_here"/>

   (2) Open [project build]/android/gradletemplate/build.gradle

   replace every
       maven {
            url "https://maven.google.com"
      }

   with
       mavenCentral()
#End

Import mojo.app
Import mojo.graphics
Import mojo.input

#If TARGET="android"
  #If ANDROID_LIBGOOGLEPLAY_AVAILABLE
     Import brl.admob
  #End
  Import "native/rewardedads.java"
#End If

Extern

Class AdmobRewarded Extends Null = "BBAdmobRewarded"
    Function GetAdmobRewarded:AdmobRewarded(adUnitId:String)
    Method ShowAdViewRewarded:Void()
    Method isLoaded:Bool()            ' was the ad loaded?
    Method earnedReward:Bool()        ' did the user earned the reward?
    Method isClosed:Bool()            ' was the ad closed?
End Class

Public

#If TARGET="android"
    #ANDROID_APP_LABEL="Rewarded ads"
    #ANDROID_APP_PACKAGE="com.icongames.rewardedAdsTest"
    #ANDROID_SCREEN_ORIENTATION="sensorPortrait"                    '"user", "portrait", "landscape"  
    #ANDROID_VERSION_CODE="001"
    #ANDROID_VERSION_NAME="0.01"     

    ' test ads
    #ADMOB_PUBLISHER_ID = "ca-app-pub-3940256099942544/5224354917"
#End

Class Game Extends App

    Global IDLE:Int = 0
    Global AD_VISIBLE:Int = 1
    Global AD_CLOSED:Int = 2
    Global UPDATE_RATE:Int = 30  

    Field state:Int
    Field admobRewarded:AdmobRewarded

    Method OnCreate()

#If TARGET="android"  
                ' test ads
                admobRewarded = AdmobRewarded.GetAdmobRewarded("ca-app-pub-3940256099942544/5224354917")
#End

        SetUpdateRate UPDATE_RATE
        state = IDLE
    End Method

    Method OnUpdate()

        Select state

            Case IDLE
                If TouchHit(0) And admobRewarded.isLoaded() Then
                    Print "Showing rewarded ad..."
                    admobRewarded.ShowAdViewRewarded()
                    state = AD_VISIBLE
                End If

            Case AD_VISIBLE
                If admobRewarded.isClosed() Then
                    state = AD_CLOSED
                End If

            Case AD_CLOSED
                If admobRewarded.earnedReward() Then
                    Print "Yay! Reward earned"
                Else
                    Print "Sorry, no reward."
                End If
                state = IDLE
        End Select

    End Method

  
    Method OnRender()

        Cls(0,0,0)

        Select state
            Case IDLE
                If admobRewarded.isLoaded() Then
                    SetColor 255,255,255
                    DrawText "Touch the screen to open the ad!", 10,10
                End If
       
            Case AD_VISIBLE
            Case AD_CLOSED
        End Select
    End Method  
End Class

Function Main()
    New Game()
End Function

native/rewardedads.java
Code:
import com.google.android.gms.ads.rewarded.RewardedAd;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.NonNull;           
import com.google.android.gms.ads.AdError;    
import com.google.android.gms.ads.MobileAds;    
import com.google.android.gms.ads.AdRequest;  
import com.google.android.gms.ads.FullScreenContentCallback;  
import com.google.android.gms.ads.LoadAdError; 
import com.google.android.gms.ads.initialization.InitializationStatus;  
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener;  
import com.google.android.gms.ads.OnUserEarnedRewardListener;
import com.google.android.gms.ads.rewarded.RewardItem;
import com.google.android.gms.ads.rewarded.RewardedAd;
import com.google.android.gms.ads.rewarded.RewardedAdLoadCallback;


class BBAdmobRewarded implements Runnable {
    static BBAdmobRewarded _admob;
    static Activity _activity;

    private RewardedAd _rewardedAd;
    boolean loaded;
    boolean earned;
    boolean closed;
    String adUnitId;
    private static final String TAG = "[Cerberus]";


    // creates an instance of the object and start the thread
    static public BBAdmobRewarded GetAdmobRewarded(String adUnitId){
        Log.d(TAG, "Google Mobile Ads SDK");

        if( _admob==null ) _admob=new BBAdmobRewarded();
        _activity = BBAndroidGame.AndroidGame().GetActivity();

        if( Variables.__bb__MobileAds_init == false ) {
            Log.d(TAG, "BBAdmobRewarded MobileAds.initialize");
            MobileAds.initialize(_activity, new OnInitializationCompleteListener() {
                @Override
                public void onInitializationComplete(InitializationStatus initializationStatus) {}
            });
            Variables.__bb__MobileAds_init = true ;
        }

        _admob.startAd(adUnitId);
        return _admob;
    }
  
    public boolean isLoaded() { return loaded; }
    public boolean isClosed() { return closed; }
    public boolean earnedReward() { return earned;     }

    public void run(){
  
        if( _rewardedAd != null ){
            Log.d(TAG, "BBAdmobRewarded run() -> _rewardedAd.show");
            _rewardedAd.show(_activity,
            new OnUserEarnedRewardListener() {
                @Override
                public void onUserEarnedReward(@NonNull RewardItem rewardItem) {
                    // Handle the reward.
                    Log.d(TAG, "The user earned the reward.");
                    int rewardAmount = rewardItem.getAmount();
                    String rewardType = rewardItem.getType();
                    earned = true;
                }
            });
          
            return;
        } else {  
            Log.e(TAG, "BBAdmobRewarded run() -> _rewardedAd = null");  
            loaded = false;
            earned = false;
            closed = false;
        }
      
        // load the first ad
        loadRewardedAd();
    }
  
    // start the thread
    private void startAd(String adUnitId){
        Log.d(TAG, "BBAdmobRewarded startAd()");
        this.adUnitId = adUnitId;
        BBAndroidGame.AndroidGame().GetGameView().post(this);
    }

    private void loadRewardedAd() {
        if (_rewardedAd == null) {
          loaded = false;
          Log.d(TAG, "BBAdmobRewarded adRequest");
          AdRequest adRequest = new AdRequest.Builder().build();

          RewardedAd.load(
              _activity,
              this.adUnitId,
              adRequest,
              new RewardedAdLoadCallback() {
                @Override
                public void onAdLoaded(@NonNull RewardedAd rewardedAd) {
                    Log.d(TAG, "BBAdmobRewarded onAdLoaded");
                    loaded=true;
                    _rewardedAd = rewardedAd;
                  
                    _rewardedAd.setFullScreenContentCallback(new FullScreenContentCallback()
                    {
                        @Override
                        public void onAdDismissedFullScreenContent() {
                            // Called when fullscreen content is dismissed.
                            //mInterstitialAd = null;
                            Log.d(TAG, "BBAdmobRewarded FullScreenContentCallback -> The ad was dismissed.");
                            closed = true;
                            _rewardedAd = null;
                            _admob.loadRewardedAd();
                        }
                              
                        @Override
                        public void onAdFailedToShowFullScreenContent(AdError adError) {
                            // Called when fullscreen content failed to show.
                            Log.d(TAG, "BBAdmobRewarded FullScreenContentCallback -> The ad failed to show.");
                            _rewardedAd = null;
                            closed = true;
                            earned = false;
                            loaded = false;
                        }
                              
                        @Override
                        public void onAdShowedFullScreenContent() {
                            // Called when fullscreen content is shown.
                            _rewardedAd = null;
                            earned = false;
                            closed=false;
                            Log.d(TAG, "BBAdmobRewarded FullScreenContentCallback -> The ad was shown.");
                        }
                    });                
                }

                @Override
                public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
                  // Handle the error.
                  Log.d(TAG, loadAdError.getMessage());
                  _rewardedAd = null;
                }

              });
            
        }
    }

    // displays the ad to the user if it is ready
    public void ShowAdViewRewarded( ){
        if (_rewardedAd != null ) {
            if( loaded ){
                Log.d(TAG, "BBAdmobRewarded ShowAdViewRewarded() -> loaded = true");
                BBAndroidGame.AndroidGame().GetGameView().post(this);
            } else {  
                Log.e(TAG, "BBAdmobRewarded ShowAdViewRewarded() -> loaded = false");
            }
        } else {  
            Log.e(TAG, "BBAdmobRewarded ShowAdViewRewarded() -> _rewardedAd = null");  
            loaded = false;
            earned = false;
            closed = false;
        }
    }
  
}

That's it. Please test this! I've tested in my old Android 4.2 tablet and on Bluestacks 4 (Android 7). Unfortunately I don't have anything newer to test on.

If you find this useful, please consider making a donation :)
 
Last edited:

Wingnut

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,284
I could try that on a new Android but the two changes that you listed, how do you go through with those because It does not work like that here.

For instance when you press compile, Ceberus sends the app to the phone with no intermediate editing.
 

SLotman

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jul 3, 2017
Messages
239
First you just "build" (or press F7). The files will be generated, but nothing will be executed. Only then you go at those files and change them.
 

Wingnut

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,284
II opened [project build]/android/app/src/main/AndroidManifest.xml
bu there is no ${ANDROID_MANIFEST_ACTIVITY}:


Screenshot 2022-11-19 at 10.37.31.png
 

Wingnut

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,284
even if i find the palce to write the xml code I still won't know what codes form Admob to put there. THis is why I said Ads are hard. Too many codes and I don't I just don't get it I need help with someone showing me how to do it.
 

SLotman

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jul 3, 2017
Messages
239
I'm sorry - its [project build]\android\gradletemplate\app\src\main\AndroidManifest.xml and its before ${ANDROID_MANIFEST_APPLICATION} - my bad :(

The value to place on 'real_app_id_generated_by_admob_here'' is given by Admob, when you create an app/ad over there. You can find it following this tutorial.
 
Last edited:

Wingnut

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,284
Okay got it. But how do i compile it now? when I press play in Cebreys it complains I need to delete the folder again and restart to be able to compile. It wont let me recompile with thte edited files.
 

Wingnut

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,284
I checked the files to makes sure CX leaves edites files alone and It does. Soits actually compiling the new Andorid app to the phone, thats good news..

The problem is, the app on the phone crashes over and over again. It never ever runs.

EDIT
partly success I got it to no crash. It's a black screen though.

I'm not supposed to change any ID's inside the CX code? I just reactivated my account after 6 months of no use (as I gave up).. so it will take 24h or so to reactivate but I can get normal banners.
 
Last edited:

Wingnut

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,284
Tonight I got it working. I'm not sure what to do with it though but it started and I clicked it away. fullscreen video with sound.
So how do you use it, is there a trigger with flag or so?

I can answer some questions you had:

* Don't know what will happen if an ad fail to load.
It gives you black screen when offline.

* I couldn't test also what happens if you close the ad before earning the reward - no matter
how much I clicked on the [x] the test ad wouldn't go away before the countdown ended.

That's right, same here, and also back button does nothing until the ad have counted to zero.
It won't write any request to touch the display to get an ad either if offline. If you go online after you started the app, it won't do anything still. YOu nee to start the app and be online for text to appear.


Of course I now also wonder how to make it possible for the user to cancel whenever, and the backbuttons hould be possible to press too.
And there should be a flag to tel the game what happened to the ad.
 
Last edited:

SLotman

Active member
3rd Party Module Dev
Tutorial Author
Joined
Jul 3, 2017
Messages
239
* Don't know what will happen if an ad fail to load.
It gives you black screen when offline.
Yeah. I tried here without connection, so I changed the code a bit to 'load' another ad if it failed. But if the connection is off, it will keep reloading forever. I'm still undecided on what would be the best approach for this.

there should be a flag to tel the game what happened to the ad
There is! admobRewarded.earnedReward() - the test program should print on the debug window a "yay! reward earned!"

I now also wonder how to make it possible for the user to cancel whenever
That's controlled by Google, not me. When you display the ad, its another view on top of yours, controlled by Admob.
Maybe it works as intended with real ads instead of this 'test' one...?

Let me just ask you one more thing: what android version did you test it on?
 

Wingnut

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,284
No you should be able to cancel i see others has the same problem so i added that code but it did not work i am not sure why. I threw it away bc i got tired of trying after trying long and hard.

The phone was was using API 31 and it did work.
I was cautios about the two messages that said you have earned. There are two similiar messages coming with some other events between so I looked long and hwr at those and tried to understand why it gives me so many things in the log. I could not find out why that was sadly.

I could dig out the code to sense dismissed ads:

Also there is a need to check for what kind of ads you use becuase if you use your own while testing your acount cancceled by misstake. This is what almost did.
 
Last edited:

Wingnut

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,284
I was able to make it mojo2 before going to work.

Code:
#REM

SETUP NEEDED:

    STEP 1
    Open [project build]\android\gradletemplate\app\src\main\AndroidManifest.xml and edit
    just before ${ANDROID_MANIFEST_APPLICATION} :

    <meta-data
        android:name="com.google.android.gms.ads.APPLICATION_ID"
        android:value="real_app_id_generated_by_admob_here"/>

   The value to place on 'real_app_id_generated_by_admob_here'' is given by Admob, when you create an app/ad over there. You can find it following this tutorial: https://support.google.com/admob/answer/7356431?hl=en

    STEP 2
    Open [project build]/android/gradletemplate/build.gradle

     replace every
 
       maven {
            url "https://maven.google.com"
       }

   with
       mavenCentral()

#End
Import mojo2

#If TARGET="android"
  #If ANDROID_LIBGOOGLEPLAY_AVAILABLE
     Import brl.admob
  #End
  Import "native/rewardedads.java"
#End If

Extern

Class AdmobRewarded Extends Null = "BBAdmobRewarded"
    Function GetAdmobRewarded:AdmobRewarded(adUnitId:String)
    Method ShowAdViewRewarded:Void()
    Method isLoaded:Bool()         ' was the ad loaded?
    Method earnedReward:Bool()     ' did the user earned the reward?
    Method isClosed:Bool()         ' was the ad closed?
End Class

Public

#If TARGET="android"
    #ANDROID_APP_LABEL="Rewarded ads"
    #ANDROID_APP_PACKAGE="com.icongames.rewardedAdsTest"
    #ANDROID_SCREEN_ORIENTATION="sensorPortrait"                    '"user", "portrait", "landscape"  
    #ANDROID_VERSION_CODE="001"
    #ANDROID_VERSION_NAME="0.01"      

    ' test ads
    #ADMOB_PUBLISHER_ID = "ca-app-pub-3940256099942544/5224354917"
#End

Class Game Extends App

    Global IDLE:Int = 0
    Global AD_VISIBLE:Int = 1
    Global AD_CLOSED:Int = 2
    Global UPDATE_RATE:Int = 30  
    Field canvas:Canvas
    Field state:Int
    Field admobRewarded:AdmobRewarded

    Method OnCreate()

#If TARGET="android"  
                ' test ads
                admobRewarded = AdmobRewarded.GetAdmobRewarded("ca-app-pub-3940256099942544/5224354917")
#End
       canvas = New Canvas()
       SetSwapInterval 1 ; SetUpdateRate 0
       '  SetUpdateRate UPDATE_RATE
        state = IDLE
    End Method

    Method OnUpdate()

        Select state

            Case IDLE
                If TouchHit(0) And admobRewarded.isLoaded() Then
                    Print "Showing rewarded ad..."
                    admobRewarded.ShowAdViewRewarded()
                    state = AD_VISIBLE
                End If

            Case AD_VISIBLE
                If admobRewarded.isClosed() Then
                    state = AD_CLOSED
                End If

            Case AD_CLOSED
                If admobRewarded.earnedReward() Then
                    Print "Yay! Reward earned"
                Else
                    Print "Sorry, no reward."
                End If
                state = IDLE
        End Select

    End Method
   
    Method OnRender()
        canvas.Clear 0,0,0
        Select state
            Case IDLE
                If admobRewarded.isLoaded() Then
                    canvas.SetColor 1,1,1
                    canvas.DrawText "Touch the screen to open the ad!", 10,10
                End If
            Case AD_VISIBLE
            Case AD_CLOSED
        End Select
        canvas.Flush
    End Method  
End Class

Function Main()
    New Game()
End Function
 

Wingnut

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,284
I'm confused about this ad thing. Unity users having the same problem got this repsonse from Google.

"I have contacted Admob Support and got the following answer:
Since you mentioned that the rewarded app can be skipped only after the countdown is done, then it is working as intended. If you want only skippable ads, you can implement rewarded interstitial ad formats instead."


In either words it might be workign correctly or not, there's no way to test yet.
 
Top Bottom