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.
Related
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
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 ...
I created an account at Admob since a month, and i added payment method since 2 days ago.
a test device showing ads successfully. but other devices don't show any thing with error code:3
Ads: Ad failed to load : 3
public class MainActivity extends AppCompatActivity implements RewardedVideoAdListener {
private AdView adView;
private Button onePlayer, twoPlayer, exit;
private InterstitialAd mInterstitialAd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MobileAds.initialize(this, getString(R.string.app_id));
MobileAds.initialize(this, initializationStatus -> {
});
mInterstitialAd = new InterstitialAd(this);
mInterstitialAd.setAdUnitId(getString(R.string.instruction));
mInterstitialAd.loadAd(new AdRequest.Builder().addTestDevice("my-device-id").build());
mInterstitialAd.setAdListener(InterstitialListener);
adView = findViewById(R.id.adView);
adView.loadAd(new AdRequest.Builder().addTestDevice("my-device-id").build());
adView.setAdListener(adListener);
}
}
and i created a listener for InterstitialAd
private AdListener InterstitialListener = new AdListener() {
#Override
public void onAdLoaded() {
// Code to be executed when an ad finishes loading.
mInterstitialAd.show();
}
#Override
public void onAdFailedToLoad(int errorCode) {
// Code to be executed when an ad request fails.
Toast.makeText(getApplicationContext(), "errorCode " + errorCode + "", Toast.LENGTH_LONG).show();
}
#Override
public void onAdOpened() {
// Code to be executed when the ad is displayed.
}
#Override
public void onAdClicked() {
// Code to be executed when the user clicks on an ad.
}
#Override
public void onAdLeftApplication() {
// Code to be executed when the user has left the app.
}
#Override
public void onAdClosed() {
// Code to be executed when the interstitial ad is closed.
}
};
and this is banner xml:
<com.google.android.gms.ads.AdView
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="#+id/adView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
ads:adSize="BANNER"
ads:adUnitId="#string/banner">
</com.google.android.gms.ads.AdView>
Note: the app doesn't uploaded to store yet!
how can i fix this problem?
This answer might help someone in future. I had the same problem. Ads were working fine in test devices. But in real device it did not display any ad.
I published my app to google play and downloaded it. In the app downloaded from google play, Ads are showing fine. I did not make any changes to the code
I am not sure why this happens, it's kind of black box.
Some answers in stack overflow says no need to publish app for showing ads. But it was not true in my case.
Your code seems fine.
Are you using this test unit ID for your banner?
ca-app-pub-3940256099942544/6300978111
Or are you using the one from your AdMob account?
My application opens a Publisher InterstitialAd whenever you start but when a user closes it reopens. This process happens constantly and then you can't use application, can anyone help me?
public void getIntertitalAds(boolean isPortraitMode)
{
interstitial = new PublisherInterstitialAd(context);
if(isPortraitMode)
interstitial.setAdUnitId(tags.getAdUnitInterstitial());
else
interstitial.setAdUnitId(tags.getAdUnitInterstitialTablet());
AdListener adListener = new AdListener() {
#Override
public void onAdLoaded() {
super.onAdLoaded();
if(interstitial!=null)
interstitial.show();
}
#Override
public void onAdClosed() {
super.onAdClosed();
interstitial = null;
}
};
// Create ad request.
PublisherAdRequest adRequest = new PublisherAdRequest.Builder()
.build();
// Begin loading your interstitial.
interstitial.setAdListener(adListener);
interstitial.loadAd(adRequest);
}
NEVER call interstitial.show() from AdListener#onAdLoaded(). You have no control over when it will be called and it presents a really poor user experience. Instead call interstitial.show() at a natural break point in your app.
There is no need to have separate AdUnitIds for portrait and landscape. Interstitials are the same regardless.
All the code in your getIntertitalAds() (sic) method should be Activity#onCreate
I strongly suspect your problems stem from a combination of 1 and 3.
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.