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
Related
I've been having this problem for 3 days. I started developing applications with test ads to update the applications published in the store. But by no means did the test ads appear in the 2 apps. I suspected it because I was using old library. But when I created a new project and tested it, I saw test ads showing. I could not see any test ads in the applications published in the store. I would be very grateful for any help.
Error code:
failed to load: 3 --> ERROR_CODE_NO_FILL
build.gradle:
implementation 'com.google.android.gms:play-services-ads:19.4.0'
//and...
dependencies {
classpath 'com.android.tools.build:gradle:3.5.3'
classpath 'com.google.gms:google-services:4.3.0'
}
Activity:
private InterstitialAd mInterstitialAd;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
MobileAds.initialize(this, "ca-app-pub-3940256099942544~3347511713");
mInterstitialAd = new InterstitialAd(this);
mInterstitialAd.setAdUnitId("ca-app-pub-3940256099942544/1033173712");
mInterstitialAd.loadAd(new AdRequest.Builder().build());
mInterstitialAd.setAdListener(new AdListener() {
#Override
public void onAdClosed() {
super.onAdClosed();
Log.d("testad","onAdClosed");
}
#Override
public void onAdFailedToLoad(int i) {
super.onAdFailedToLoad(i);
Log.d("testad","onAdFailedToLoad"+i);
mInterstitialAd.loadAd(new AdRequest.Builder().build());
}
#Override
public void onAdLeftApplication() {
super.onAdLeftApplication();
Log.d("testad","onAdLeftApplication");
}
#Override
public void onAdOpened() {
super.onAdOpened();
Log.d("testad","onAdOpened");
}
#Override
public void onAdLoaded() {
super.onAdLoaded();
Log.d("testad","onAdLoaded");
}
});
Android Manifest:
//...
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-3940256099942544~3347511713" />
</application>
I tried:
I reset the ad ID from device settings.
I added the device as a test device.
I tried with different network connection.
I tried with different device.
I'm facing the same issue in React Native. First, my test ads were showing then I uploaded the app to the google play store and the app store. A few days later ads limit was marked on my account after 15 days that limit is removed but now ads are not showing even not Test ads. I changed the bundle name and then test ads show. It means integration is ok there must be an issue on the account side.
If your test ads are working, but your real ads are not loading. It doesn't mean that your implementation is wrong. Admob doesn't show real until your app gets a certain amount of traffic. If there is low traffic on your app, then AdMob would show very few or no ads.
failed to load: 3 --> ERROR_CODE_NO_FILL
This error is clearly showing AdMob has no fill for your ads now. If test ads are working fine, then your real ads would load fine too, once AdMob starts to deliver them.
Don't try to load real ads from your devices, Admob will place a limited ad serving if they detect you are trying to load ads by yourself.
You are using an older AdMob SDK, the current version is 20.4.0. There are many API changes introduced in version 19.7.0 and some classes are deprecated and renamed.
The interstitial constructor you are using for initialization is now deprecated. You have to use the static load() method for creating an interstitial ad instance.
Now you have to initialize and use Interstitial ads like this
private InterstitialAd mInterstitialAd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
.
.
.
AdRequest adRequest = new AdRequest.Builder().build();
InterstitialAd.load(this,"ca-app-pub-3940256099942544/1033173712", adRequest,
new InterstitialAdLoadCallback() {
#Override
public void onAdLoaded(#NonNull InterstitialAd interstitialAd) {
// The mInterstitialAd reference will be null until
// an ad is loaded.
mInterstitialAd = interstitialAd;
Log.i(TAG, "onAdLoaded");
}
#Override
public void onAdFailedToLoad(#NonNull LoadAdError loadAdError) {
// Handle the error
Log.i(TAG, loadAdError.getMessage());
mInterstitialAd = null;
}
});
}
Now show it by calling show() method
if (mInterstitialAd != null) {
mInterstitialAd.show(MyActivity.this);
} else {
Log.d("TAG", "The interstitial ad wasn't ready yet.");
}
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 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.
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.