2

I am trying to use the AdMob Rewarded Ad in my Android application. In order to include it in the refered app, I need to wait for the rewarded video to load after the user click the buttom. I am trying it throughout the code bellow, but I get the error:

java.lang.IllegalStateException: showAd must be called on the main UI thread.

When the buttom is clicked:

b_r_ans.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        if(isSomBotaoLigado() && loaded[0])
            soundPool.play(soundID, MyApplication.getVolumeBotao(), MyApplication.getVolumeBotao(), 1, 0, 1f);

        Toast.makeText(MyApplication.getAppContext(),carregando_rv, Toast.LENGTH_LONG).show();




        Thread t_rv = new Thread(new Runnable() {
            public void run() {
                while(!rv_loaded){
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }


            }
        });
        t_rv.start();

        try {
            t_rv.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        mRewardedVideoAd.show();

    }
});

Overrided the listener:

@Override
    public void onRewardedVideoAdLoaded() {
        Toast.makeText(this, "onRewardedVideoAdLoaded", Toast.LENGTH_SHORT).show();
        rv_loaded = true;
    }

Using the mRewardedVideoAd.isLoaded() function triggers the same issue.

How can I wait for the video to load properly?

Siqueira
  • 423
  • 1
  • 7
  • 29

5 Answers5

1

It appears to happen that you are calling show from a different thread to the UI so I'd try to force its execution on the main thread like:

// Get a handler that can be used to post to the main thread
Handler mainHandler = new Handler(Looper.getMainLooper());

Runnable myRunnable = new Runnable() {
    @Override 
    public void run() {
         if (mRewardedVideoAd.isLoaded()) {
             mRewardedVideoAd.show();
    }
};
mainHandler.post(myRunnable);
fmaccaroni
  • 3,846
  • 1
  • 20
  • 35
  • Running it in the main thread locks the application. The application breaks at the end. – Siqueira Dec 27 '17 at 19:42
  • I've editted the answer adding isLoaded before showing the ad. Maybe it's not fully loaded (even though it seems to be if the thread t_rv finishes) – fmaccaroni Dec 27 '17 at 19:53
  • Also check that the thread is ending hence the video has loaded because if the video has not finished loading the while in the thread will never end and your app will hang – fmaccaroni Dec 27 '17 at 19:59
1

You can also disable the button until the ad is loaded, then in the onRewardedVideoAdLoaded function enable the button:

override fun onRewardedVideoAdLoaded() {
        ad_btn.isEnabled = true
    }

Hope it helps. This is the implementation that I am using.

Andrax92
  • 11
  • 2
0

Solved it through this code:

@Override
    public void onRewardedVideoAdLoaded() {
        //Toast.makeText(this, "onRewardedVideoAdLoaded", Toast.LENGTH_SHORT).show();
        rv_loaded = true;
        if(goToAnswers)
            mRewardedVideoAd.show();

        goToAnswers = false;
    }

b_r_ans.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if(isSomBotaoLigado() && loaded[0])
                    soundPool.play(soundID, MyApplication.getVolumeBotao(), MyApplication.getVolumeBotao(), 1, 0, 1f);

                Toast.makeText(MyApplication.getAppContext(),carregando_rv, Toast.LENGTH_LONG).show();

                if(mRewardedVideoAd.isLoaded())
                    mRewardedVideoAd.show();
                else goToAnswers=true;


            }
        });
Siqueira
  • 423
  • 1
  • 7
  • 29
0

This code will show a ProgressDialog while loading the reward video:

package com.mountzoft.waitForrewardvideoProperly;

import android.app.ProgressDialog;
import android.content.Context;

import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.reward.RewardItem;
import com.google.android.gms.ads.reward.RewardedVideoAd;
import com.google.android.gms.ads.reward.RewardedVideoAdListener;



public class MainActivity extends AppCompatActivity implements RewardedVideoAdListener {

    private RewardedVideoAd mAd;
    private ProgressDialog mProgressDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setMessage("Please wait... Loading Reward Video Ad!");
        mProgressDialog.setCancelable(false);
    }


    private final showRewardVideoAd() {
        mProgressDialog.show();
        initializeRewardVideoAd();
        loadRewardedVideoAd();
    }

    private void initializeRewardVideoAd(){
        String adMobAppId = BuildConfig.AD_MOB_APP_ID; //id is stored in build gradle file
        MobileAds.initialize(this, adMobAppId);
        mAd = MobileAds.getRewardedVideoAdInstance(this);
        mAd.setRewardedVideoAdListener(this);
    }

    private void loadRewardedVideoAd() {
        String admobAdUnitId = BuildConfig.ADMOB_AD_UNIT_ID;//id is stored in build gradle
        mAd.loadAd(admobAdUnitId,
                new AdRequest.Builder().build());
    }

    @Override
    public void onRewardedVideoAdLoaded() {
        mAd.show();
    }

    @Override
    public void onRewardedVideoAdOpened() {
        mAd = null;
    }

    @Override
    public void onRewardedVideoStarted() {
        mProgressDialog.dismiss();
    }

    @Override
    public void onRewardedVideoAdClosed() {
    }

    @Override
    public void onRewarded(RewardItem rewardItem) {
    }


    @Override
    public void onRewardedVideoAdLeftApplication() {

    }

    @Override
    public void onRewardedVideoAdFailedToLoad(int i) {
    }

    @Override
    public void onRewardedVideoCompleted(){
    }

}
Bless
  • 5,052
  • 2
  • 40
  • 44
Jithin Jude
  • 840
  • 14
  • 19
0

If you need to wait until rewarded ad loading use SingleLiveEvent. Please refer following code snippet.

private val isRewardedAdLoaded: LiveData<Event<Boolean>>
    get() = _isRewardedAdLoaded

private var _isRewardedAdLoaded: MutableLiveData<Event<Boolean>> = MutableLiveData()

I used this is in fragment. So this from onViewCreated()

rewardedAd = createAndLoadRewardedAd()

and I post loading state as following

private fun createAndLoadRewardedAd(): RewardedAd {
    val rewarded = RewardedAd(requireContext(), getString(R.string.admob_rewarded_id_test))
    val adLoadCallback = object : RewardedAdLoadCallback() {
        override fun onRewardedAdLoaded() {
            Log.e(TAG, "onRewardedAdLoaded")
            _isRewardedAdLoaded.postValue(Event(true))
        }

        override fun onRewardedAdFailedToLoad(errorCode: Int) {
            _isRewardedAdLoaded.postValue(Event(false))
        }
    }
    rewarded.loadAd(Builder().build(), adLoadCallback)
    return rewarded
}

this is rewarded ad show method

private fun showRewardedAds(rewarded: RewardedAd) {
    rewarded.show(requireActivity(), object : RewardedAdCallback() {

        override fun onRewardedAdOpened() {
            Log.e(TAG, "onRewardedAdOpened")
        }

        override fun onRewardedAdClosed() {
            Log.e(TAG, "onRewardedAdClosed")
            rewardedAd = createAndLoadRewardedAd()
        }

        override fun onUserEarnedReward(rewardItem: RewardItem) {
            Log.e(TAG, "onUserEarnedReward")
            translateText()
        }

        override fun onRewardedAdFailedToShow(errorCode: Int) {
            translateText()
        }
    })
}

Finally I called as following

R.id.btnTranslate -> {

    if (rewardedAd.isLoaded){
        showMessage(
            getString(R.string.translate_ads_show_warning_title),
            getString(R.string.translate_ads_show_warning_msg)
        )
    } else {
        progress.setVisible(true)
        isRewardedAdLoaded.observe(viewLifecycleOwner, Observer {
            it.getContentIfNotHandled()?.let { loaded ->
                if (loaded and progress.isVisible){
                    progress.setVisible(false)
                    showMessage(
                        getString(R.string.translate_ads_show_warning_title),
                        getString(R.string.translate_ads_show_warning_msg)
                    )
                }
            }
        })
    }
}
Dilanka Laksiri
  • 408
  • 3
  • 12