How to add onAdClick callback in rewarded-ads? - AdMob - Android - android

I am trying to implement ads in my App. I go though the official documentation and implemented interstitial ads into my app. It is working fine. As Described Here
As I also know that admob will block my admob account if any malicious user clicks on my ads again and again. So to protect that, I had setup a threshold of 3 clicks i.e. If a user try to click on my ads more than 3 times in a single day, I will not show ads for next 48 hours. So, to implement this functionality with interstitial ads I use onAdClick() callback in interstitial ads. As shown here
But, when I try to implement the same thing with rewarded ads, I find that their is no such callback which can help me to detect clicks on rewarded ads. See here.
Can someone help me to achieve this functionality. Is there any alternative ways? Please help me to come out from this scenario. If it is not possible than what I can do to protect my admob account from malicious users?

Method 1
There is legacy API available for the rewarded ad Check here for more information... Rewarded Video Ads (Legacy API)
So how it works? Check the code below
public class MainActivity extends AppCompatActivity {
private RewardedVideoAd mRewardedVideoAd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRewardedVideoAd= MobileAds.getRewardedVideoAdInstance(this);
mRewardedVideoAd.loadAd("ca-app-pub-3940256099942544/5224354917",new AdRequest.Builder().build()); // You need to pass your rewared video ad Id here...
mRewardedVideoAd.setRewardedVideoAdListener(new RewardedVideoAdListener() {
#Override
public void onRewardedVideoAdLoaded() {
}
#Override
public void onRewardedVideoAdOpened() {
}
#Override
public void onRewardedVideoStarted() {
}
#Override
public void onRewardedVideoAdClosed() {
}
#Override
public void onRewarded(RewardItem rewardItem) {
//Reward your user here....
Toast.makeText(MainActivity.this, "Congrats you got reward", Toast.LENGTH_SHORT).show();
}
#Override
public void onRewardedVideoAdLeftApplication() {
//User clicked on ad here write your caching code here....
Toast.makeText(MainActivity.this, "Clicked on Ad", Toast.LENGTH_SHORT).show();
}
#Override
public void onRewardedVideoAdFailedToLoad(int i) {
}
#Override
public void onRewardedVideoCompleted() {
}
});
findViewById(R.id.my_button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mRewardedVideoAd.isLoaded()) {
mRewardedVideoAd.show();
} else {
Toast.makeText(MainActivity.this, "Please Wait..", Toast.LENGTH_SHORT).show();
}
}
});
}
}
Pros Using this method: It does your work you can get callbacks on clicking ad
Cons Google recommends new RewardedAPI ..(Although legacy API still works fine .... )
Why does Google recommend new RewardedAPI over Legacy?
The new rewarded API is an improvement over the legacy API because
it allows you to Cache multiple ads.
The legacy rewarded API only lets you load one ad at a time, and you can't load a second ad until the first one finishes.
The new rewarded API lets you cache multiple ads at the same time.
Access the reward value at ad load time. The legacy implementation
only provides access to the reward when it's time to grant the user
the reward.
For apps that use the reward value from the AdMob UI, this improvement enables you to show the user their reward before they watch the ad. Initialize mediation partners. If you use rewarded mediation, the newly rewarded APIs support initialization of mediation adapters before the first ad load. The legacy rewarded API
does not initialize adapters, and mediation adapters were more likely to time out on the first request of a session. Migrating from the legacy rewarded API? Make sure to update your mediation adapters to the latest version, as the adapters had to migrate as well.
Method 2:
Since the new Rewarded API doesn't have any callbacks for click events on the ad I recommend you to cache the total number of times the user requested for ads ... limit the number of times they can request that ads
For example: In 24 hrs they can only request 3 times
Pros: As listed above Google recommends it for certain reasons
Cons: It doesn't solve your problem ...

Related

Can I called loadMethod while Ad is closed/onAdDismissed - AdMob?

I want integrated AdMob into my app. but here is an issue we manually need to reload Ad for showing. I want to try when some close/Dismiss the Ad automatically load again that I called it again onAdDissmissed method. Is this a policy violation? or Is a good programming practice or not?
Here my code oncreate method
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
loadMethodAdMob();
}
load Method
public void loadMethodAdMob() {
AdRequest adRequest = new AdRequest.Builder().build();
InterstitialAd.load(this, AD_UNIT_ID, adRequest, new InterstitialAdLoadCallback() {
#Override
public void onAdLoaded(#NonNull InterstitialAd interstitialAd) {
// will be null until an ad is loaded.
MyActivity.this.interstitialAd = interstitialAd;
mToast("Ad Loaded");
interstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() {
#Override
public void onAdDismissedFullScreenContent() {
MyActivity.this.interstitialAd = null;
mToast("The ad was dismissed.");
InterstitialAdMob(); // i called it here is this ok
}
#Override
public void onAdShowedFullScreenContent() {
mToast("The ad was shown.");
}
});
}
});
}
button click
public void buttonClickShowAd(){
if (interstitialAd != null) {
interstitialAd.show(this);
} else {
mToast("Ad did not load");
requestForReload();
}
}
You can load n-number of interstitial ads in advance so that it will be available when show method is called. Above code is perfectly fine.
Reference - https://developers.google.com/admob/android/interstitial#some_best_practices
Allow for adequate loading time.
Just as it's important to make sure you display interstitial ads at an appropriate time, it's also important to make sure the user doesn't have to wait for them to load. Loading the ad in advance by calling load() before you intend to call show() can ensure that your app has a fully loaded interstitial ad at the ready when the time comes to display one.
Don't flood the user with ads.
While increasing the frequency of interstitial ads in your app might seem like a great way to increase revenue, it can also degrade the user experience and lower clickthrough rates. Make sure that users aren't so frequently interrupted that they're no longer able to enjoy the use of your app.
However you might also want to check Disallowed interstitial implementation policy when you load multiple objects in advance.
https://support.google.com/admob/answer/6201362?hl=en

Showing Admob Interstitial ads on Activity onResume()

I am loading ads in a static manner on Activity's onCreate() method if not already loaded and on onResume() method. I am showing ads after 3-4 intervals.
Is it against google Admob's policy to show Interstitial ads on Activity onResume()?
I've gone through this article, where it says: Do not place interstitial ads on app load, but not sure I am breaking it or not. am I?
And if user gets a phone call while using app, when he hangs up, onResume() is called again. So, it might show an Interstitial ad. Am i breaking the law: It should be clear to the user which application the ad is associated with or implemented on, mentioned here?
Simplified version of my code is given:
AdmobInterstitial.java
public class AdmobInterstitial {
private static InterstitialAd mInterstitialAd;
public static InterstitialAd getInterstitial(final Context context) {
if(mInterstitialAd==null)
{
final AdRequest adRequest= new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
mInterstitialAd = new InterstitialAd(context.getApplicationContext());
mInterstitialAd.setAdUnitId(Utility.INTERSTITIAL);
mInterstitialAd.setAdListener(new AdListener() {
#Override
public void onAdClosed() {
mInterstitialAd.loadAd(adRequest);
}
});
mInterstitialAd.loadAd(adRequest);
}
return mInterstitialAd;
}
public static void counter(Application app, ShowAdInterface mmActivity)
{
SharedPreferences pref = app.getSharedPreferences(Utility.SHARED_PREF_NAME , MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
int my_counter=pref.getInt("banner_count",0);
if(my_counter>0&& my_counter%3==0) {
if(!mmActivity.showAd()) {
my_counter--;
}
}
my_counter++;
editor.putInt("banner_count",my_counter);
editor.apply();
}
}
ShowAdInterface
public interface ShowAdInterface {
public boolean showAd();
}
MainActivity.java
public class MainActivity extends AppCompatActivity implements ShowAdInterface{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mInterstitialAd= AdmobInterstitial.getInterstitial(this);
}
#Override
protected void onResume() {
super.onResume();
AdmobInterstitial.counter(getApplication(),this);
}
}
I am using this kinda method and technique in many of my apps for many years now. Occassionally, every half a year, I get a mail from google admob about a little thing which they dislike. I usually wait for this to happen and then take action because they dont just ban you, they'll ask you nicely first. So just respond to that.
Anyway, regarding your matter: Always LOAD the ad on app load and show the ad in a manner, that no "accidental" clicks are produced. This is what google hates the most, so this is where you will get auto detected and receive a mail to change it. It really depens on your app. If you see the ad loading just fine without anyone accidentally clicking on them everthing is fine. So your code is probably ok, but debugging will give a finite answer! Good luck!
I think it's alright. Until you don't take any accidental clicks from the user, you are good to go. We are loading ads onResume() and we didn't find any problem so far.

Facebook Audience Network returns error "Ad was re-loaded too frequently"

I try to add Facebook banner to my Android App. It works good with my LG D-405, but returns "Ad was re-loaded too frequently" with Samsung Galaxy S5.
adView = new AdView(getActivity(), "-------", AdSize.BANNER_HEIGHT_50);
adView.setAdListener(new AdListener() {
#Override
public void onError(Ad ad, AdError adError) {
if(getActivity()!=null) {
((MyApplication) getActivity().getApplication()).getDefaultTracker().send(
new HitBuilders.EventBuilder()
.setCategory("Facebook AdView")
.setAction("error")
.setLabel(adError.getErrorMessage())
.setValue((long) adError.getErrorCode())
.build()
);
}
}
#Override
public void onAdLoaded(Ad ad) {
if(!layout.getChildAt(2).equals(adView)) {
layout.addView(adView, 2, new LinearLayout.LayoutParams((int) (AdSize.BANNER_HEIGHT_50.getWidth() * MainActivity.density), (int) (AdSize.BANNER_HEIGHT_50.getHeight() * MainActivity.density)));
}
}
#Override
public void onAdClicked(Ad ad) {
}
});
//adView.disableAutoRefresh();
adView.loadAd();
I too got the same issue and the it seems that you must have the Facebook app installed on the device and have logged in within the last 30 days.
Also, I found this - https://developers.facebook.com/docs/audience-network/faq#a12
Source
Here is the solution if you are using emulator:
in logcat search for AdSettings.addTestDevice. You will find something like "AdSettings.addTestDevice("3b656c58-53ab-43a8-a0d6-d1f82abdf251");"
Copy this line to your code.
You are done.
According to facebook's documentation, ad request frequency has certain limit and you should wait 30 minutes before making an other ad request if you received this error.
Code=1002 “Load Too Frequently”
Ad Requests are based on a combination of:
Device ID
Placement ID
Display Format (Banner, Interstitial, Native)
Your application should attempt to make another request after 30 minutes. We also suggest adjusting your Refresh Rate or Request Rate.

Android AdRequest returns only onAdFailedToLoad AdRequest.ERROR_CODE_NO_FILL

My application has been on the Google Play store for a month and everything was working fine. Two days ago I added it to the "Designed for families" category. I received acceptance and congratulations from the Google team. Since this, my Interstitials have stopped showing. I receive AdRequest.ERROR_CODE_NO_FILL.
InterstitialAd interstitialAd;
Bundle extras = new Bundle();
extras.putBoolean("is_designed_for_families", true);
AdRequest adRequest = new AdRequest.Builder()
.addNetworkExtrasBundle(AdMobAdapter.class, extras)
.build();
interstitialAd = new InterstitialAd(this);
interstitialAd.setAdUnitId(InterstitialSample.AD_UNIT_ID);
interstitialAd.loadAd(adRequest);
interstitialAd.setAdListener(new AdListener() {
#Override
public void onAdLoaded() {
Log.d("Tim", "OK");
}
#Override
public void onAdFailedToLoad(int errorCode) {
String message = String.format("onAdFailedToLoad (%s)", InterstitialSample.getErrorReason(errorCode));
Log.d("Tim", message);
}
});
I didn't change the package name. Also, I tried changing the AD_UNIT_ID with no success.
There doesn't appear to be anything wrong with your code. I think you're receiving a genuine "no fill" response.
Ads that are deemed as child- and family-friendly are a subset of the broader ads pool. If you show ads today, after opting-in to the Designed for Families program, you might notice fewer filled impressions and lower revenue. We're working on increasing the pool of ads that are eligible to serve to DFF apps.
It is not a bug. Just a few ads has characteristics "for children 5 years" or "for children 8 years". Remove your app from "Design for families" category for showing ads or wait until there will be advertising with similar characteristics.
I have the similar issue with regular banner ads:
In April 17th I added the app to the new "Designed for Families" program with settings:
Family Category: Education, Age Group: Ages 5 & Under, Ages 6-8, Displaying Ads: Yes
I checked the requirements and ad policies - my app is compliant.
The app was successfully approved by Google Developer team.
After opening the case in Admob, they asked me to add in source the code that sets "is_designed_for_families" to true and calls the tagForChildDirectedTreatment() method for ad requests served to a child audience. Upon seeing both"is_designed_for_families" and tagForChildDirectedTreatment() set to true, AdMob will return Designed for Families-compliant ads for that ad request.
I did it, but nothing changes - still receiving "No fill from ad server."
Since April it is near two months my app received ZERO ads.
It seems that the pool of kids friendly ads is empty.
I am still waiting for issue to be resolved.
I think that the problem is that Admob did not included the "Designed for Families" category in ads campaign at all!!!
I personally checked it and did not seen this option when setting advertising campaign!
I think missing this
/**
* Called when leaving the activity
*/
#Override
public void onPause() {
if (adView != null) {
adView.pause();
}
super.onPause();
}
/**
* Called when returning to the activity
*/
#Override
public void onResume() {
super.onResume();
if (adView != null) {
adView.resume();
}
}
/**
* Called before the activity is destroyed
*/
#Override
public void onDestroy() {
if (adView != null) {
adView.destroy();
}
super.onDestroy();
}

How to get test ad Banners and test Interstitial ads working for adMob?

I am trying to setup adMob ads. I have two questions:
1) Am I using adListener interface correctly?
2) How come I am unable to see ad Interstitials?
Lets start with the adListener. As far as what I understood from the instructions, adListener is an interface. So I created an interface.
import com.google.ads.AdRequest;
import com.google.android.gms.ads.AdView;
public interface AdListener {
public void onReceiveAd(AdView ad);
public void onFailedToReceiveAd(AdView ad, AdRequest.ErrorCode error);
public void onPresentScreen(AdView ad);
public void onDismissScreen(AdView ad);
public void onLeaveApplication(AdView ad);
}
Then in my main class I implemented AdListener, and once I did I was prompted to add unimplemented methods (all the methods from the interface).
public class MainActivity extends Activity implements AdListener {
// other code for the body (here). Just showing the methods and implement
#Override
public void onReceiveAd(AdView ad) {
Log.d(TAG, "onReceiveAd");
Toast.makeText(this, "onReceiveAd", Toast.LENGTH_SHORT).show();
}
#Override
public void onFailedToReceiveAd(AdView ad, ErrorCode error) {
Log.d(TAG, "onFailedToReceiveAd");
Toast.makeText(this, "onFailedToReceiveAd", Toast.LENGTH_SHORT).show();
}
#Override
public void onPresentScreen(AdView ad) {
Log.d(TAG, "onPresentScreen");
}
#Override
public void onDismissScreen(AdView ad) {
Log.d(TAG, "onDismissScreen");
}
#Override
public void onLeaveApplication(AdView ad) {
Log.d(TAG, "onLeaveApplication");
}
}
My reason for thinking this does nothing is that I am not receiving my logs. I added toasts to double confirm I was not missing something. I think there is another step I am missing for this to work.
Now for the ads part. I thought I followed the instructions well, and my banners work in fact. But my ad interstitials do not work. This is what I have for the banners and the interstitials.
Starting with code snippet from my xml for the banner
<com.google.android.gms.ads.AdView
android:id="#+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
ads:adUnitId="I_ADDED_CORRECT_ADUNIT_ID"
ads:adSize="BANNER" />
In my main Activity, I have the following code. Again, I want to see test ads:
// setup ad banner and interstitial
final TelephonyManager tm = (TelephonyManager)getBaseContext()
.getSystemService(Context.TELEPHONY_SERVICE);
String testDeviceId = tm.getDeviceId();
Log.d(TAG, "testDeviceId retrieved(" + testDeviceId + ")");
// create interstitial
interstitial = new InterstitialAd(this);
interstitial.setAdUnitId("I_ADDED_CORRECT_ADUNIT_ID");
// ad banner
adView = (AdView)this.findViewById(R.id.adView);
// request test interstitial ads
AdRequest adRequestInterstitial = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.addTestDevice(testDeviceId)
.build();
// request test banner ads
AdRequest adRequestBanner = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.addTestDevice(testDeviceId)
.build();
//load interstitial ads
interstitial.loadAd(adRequestInterstitial);
displayInterstitial();
// load banner ads
adView.loadAd(adRequestBanner);
//NOTE: the above code is all in onCreate().
//diaplayInterstitial is outside of onCreate()
public void displayInterstitial() {
if (interstitial.isLoaded()) {
Log.d(TAG, "displayInterstitial()");
interstitial.show();
}
}
Lets see what else to tell you? Awww, yes! I also have the permissions already set in the manifest. Permissions = INTERNET, ACCESS_NETWORK_STATE, ACCESS_WIFI_STATE, READ_PHONE_STATE.
I went to project properties and added the google-play-services_lib
This is my whole setup! I have tried a number of things, because I had some 'feelings' about what may be the issue. First, I thought that maybe test ad banners and test ad interstitials cannot be requested at the same time. So I moved interstitial code to onStart(). But then, I was not sure if this was necessary, beneficial or worse (and it did not work!). My second thought was that everything works fine, and once I publish my app all will be good. But regardless, my logs are not working for the AdListener. If I can get that going, I think I can start verifying with more confidence of what is going on.
Thank you in advance for your help.
Log SS
OK, several problems here.
1) No you are not using the AdListener interface correctly.
Don't create your own interface. AdMob already supplies an AdListener interface. You do need to implement it however.
NB personally I would create an anonymous implementation of the AdListener instead of adding it to the Activity, but that's a design design for yourself.
Next you need to attach your listener to your AdView. So in your #onCreate
// load banner ads
adView.setAdListener(new AdListener() {
...
});
adView.loadAd(adRequestBanner);
2) You are unlikely to see any Interstitials with the code above because you are attempting to display immediately after requesting. It is extremely unlikely that an Interstitial has been downloaded in that short time frame. And in any case you really don't want to display an interstitial every time your Activity is created, it is a poor user experience.
Move your call to displayInterstitial() to some later point in your app life cycle, such at the end of a game session or between levels etc.
Last I looked at admob the interstitial ads were invite only. Meaning they would contact you if they felt your apps were a good fit with that type of advertising.

Categories

Resources