I am using interstitial ads from Admob in my app. Google rejects my app and claims ad fraud. They say that my app displays an ad after exiting the app.
I have changed my ad code to be sure that ad loading and ad displaying only happens when the activity is running and the app is in the foreground. Still they reject my app and claim ad fraud.
I am just doing basic interstitial code here:
implementation 'com.google.android.gms:play-services-ads:19.7.0'
public class AdManager {
boolean activityStarted;
public void onStart() {
activityStarted=true;
}
public void onStop() {
activityStarted=false;
}
public void initializeAds(Context context) {
MobileAds.initialize(context);
MobileAds.setAppMuted(true);
List<String> testDeviceIds = Arrays.asList("some id");
RequestConfiguration configuration =
new RequestConfiguration.Builder().setTestDeviceIds(testDeviceIds).build();
MobileAds.setRequestConfiguration(configuration);
}
public InterstitialAd getInterstialAdWithUnit(Context context) {
InterstitialAd mInterstitialAd = new InterstitialAd(context);
mInterstitialAd.setAdUnitId(BuildConfig.INTERSTITIAL_AD_UNIT_ID);
setAdListener(mInterstitialAd);
checkNewAdNeeded(mInterstitialAd);
return mInterstitialAd;
}
public void setAdListener(InterstitialAd mInterstitialAd) {
mInterstitialAd.setAdListener(new AdListener() {
#Override
public void onAdClosed() {
super.onAdClosed();
checkNewAdNeeded(mInterstitialAd);
}
});
}
public void showAdIfNeeded(InterstitialAd mInterstitialAd) {
if (activityStarted && mInterstitialAd.isLoaded())
mInterstitialAd.show();
else {
checkNewAdNeeded(mInterstitialAd);
}
}
public void requestNewInterstitial(InterstitialAd mInterstitialAd) {
AdRequest adRequest = new AdRequest.Builder()
.build();
mInterstitialAd.loadAd(adRequest);
}
public void checkNewAdNeeded(InterstitialAd mInterstitialAd) {
//do not load ad when acticity is stopped
if (activityStarted && !mInterstitialAd.isLoading() && !mInterstitialAd.isLoaded())
requestNewInterstitial(mInterstitialAd);
}
}
public class FullscreenActivity extends AppCompatActivity {
AdManager adManager=new AdManager();
public void onButtonClicked() {
//call another activity when Button is clicked and wait for return to display ad
activity.startActivityForResult(intent, requestCode);
runOnUiThread(new Runnable() {
#Override
public void run() {
adManager.checkNewAdNeeded(mInterstitialAd);
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//back from other activity, try to display ads only if app has focus
if ( from activity xy) {
if (mHasFocus)
showAdWhileHasFocus();
else
showAdWhenHasFocus=true;
}
}
#Override
protected void onStart() {
super.onStart();
adManager.onStart();
}
#Override
protected void onStop() {
adManager.onStop();
super.onStop();
}
boolean showAdWhenHasFocus;
public void showAdWhileHasFocus() {
showAdWhenHasFocus=false;
adManager.showAdIfNeeded(mInterstitialAd,promotionAndAdsEvent);
}
boolean mHasFocus=false;
#Override
public void onWindowFocusChanged(boolean hasFocus) {
if (!hasFocus) {
} else {
if (showAdWhenHasFocus)
showAdWhileHasFocus();
}
super.onWindowFocusChanged(hasFocus);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
}
I recently faced this issue. But got my app update approved after the following update:
We were having Interstitial ad right while opening the app, This was causing the next screen (Home dashboard) banner ad to hide behind the interstitial add. So I removed the interstitial. This got us the problem fixed.
It might be that playstore/Admob doesn't accept ad at app start, Might be they are trying to force us to use their app open ad instead of interstitial or any other ad unit.
In my case it turned out to be an old version in the test track. In the first version I had an interstitial when exiting the app - which is not allowed. I fixed the issue, but still my app got rejected. After about 10 more tries, I realized that the first version of the app (with the interstitial on exit) was still in the test track, so I removed (or updated) the test track version, and my app was approved.
Seems like after 5 months of app rejections with ad fraud claims my apps are passing review process again. The final change I made was to change the Interstitial class in my AdMob lib to the new API.
import com.google.android.gms.ads.interstitial.InterstitialAd;
InterstitialAd mInterstitialAd;
MobileAds.initialize(...
mInterstitialAd.setFullScreenContentCallback(...
mInterstitialAd.show(...
Admob has made a lot of restructuring and I was using the legacy API. Though it was not declared as legacy until a few weeks ago. The first claim was for version 19.4.0 (https://developers.google.com/admob/android/rel-notes) and it continued until version 19.7.0. Here is a discussion about the topic. https://groups.google.com/g/google-admob-ads-sdk/c/XTJ9kcgxvbY
Related
Good afternoon. I'm trying to implement Google Ad Manager to the project (not AdMob) to render the advertising content.
According to my needs, I'm using Native ads (not Banner) with the AdSize.FLUID.
For some reason when I'm trying to set AdListener to PublisherAdView.
onAdClicked() callback doesn't trigger (other callbacks works perfectly).
Has somebody faced that strange issue and how have you solved it?
P.S. onAdClicked() callback works if I load advertising content via AdLoader.Builder(), but I cannot use it due to the project structure.
P.P.S I'm using the following version of the play services ads version
implementation 'com.google.android.gms:play-services-ads:19.6.0'
PublisherAdView publisherAdView = new PublisherAdView(context);
publisherAdView.setAdUnitId(AD_UNIT_ID);
publisherAdView.setAdSizes(AdSize.FLUID);
publisherAdView.setAdListener(new AdListener() {
#Override
public void onAdClosed() {
super.onAdClosed();
}
#Override
public void onAdFailedToLoad(LoadAdError loadAdError) {
Log.e("!", "onAdFailedToLoad: ");
super.onAdFailedToLoad(loadAdError);
}
#Override
public void onAdOpened() {
Log.e("!", "onAdOpened: " );
super.onAdOpened();
}
#Override
public void onAdLoaded() {
Log.e("!", "onAdLoaded: " );
super.onAdLoaded();
}
#Override
public void onAdClicked() {
super.onAdClicked();
Log.e("!", "onAdClicked: ");
}
});
PublisherAdRequest.Builder builder = new PublisherAdRequest.Builder();
publisherAdView.loadAd(builder.build());
I've didn't find how to solve this issue.
I had some restrictions because of project structure, so I've wrapped Google ads view
with a custom view (nothing special, just a container with ad view and placeholder + some methods for building ad, and changing placeholder visibility).
With this solution, I'm able to use AdLoader.Builder().
My Ads donot show.
I am developing an app that requires Ads. Currently for testing, I have the app in the Internal Test Track of Google Play console for closed Testing. So, I cannot link it to an app in Play store in Admob.
So, to test them, all the while I have been Sample Test Ad Units, specifically Interstitial and Rewarded Video Ads. They load fine.
Today, I decided to switch to production Ads, as I wanted to release the App. So , I have created new Ad Units for both Rewarded and intersitial. Replaced the test Ad ID units with production Ad Unit IDs. I see "Ad failed to load : 0" .
Instead of using sample Ad Units, I tried making my device set Test Device. I see the follwing log
I/Ads: This request is sent from a test device.
I/Ads: Ad failed to load : 0
I am not sure what the issue is. I am still in the internal Test Track. Is the an issue? Do the production Ads work only when linked to an app in Google Play?
Please let me know where I am going wrong. Please see the attached image for Admob Ad units
The code is as show below:
Manifest.xml:
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-xxxxxxxxxxxxxxxx~xxxxxxxxxx" />
build.gradle:
implementation 'com.google.android.gms:play-services-ads:19.2.0'
Implementing AdMob :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Rest of the code
MobileAds.initialize(this, new OnInitializationCompleteListener() {
#Override
public void onInitializationComplete(InitializationStatus initializationStatus) {
Log.w(TAG, " initialized mobile ad");
}
});
List<String> testDeviceIds = Arrays.asList("xxxxxxxxxxxxxxxxxxxxxxxxx");
RequestConfiguration configuration =
new RequestConfiguration.Builder().setTestDeviceIds(testDeviceIds).build();
MobileAds.setRequestConfiguration(configuration);
}
public void loadInterstitialAd(){
mInterstitialAd = new InterstitialAd(this);
this.rewardedAd = new RewardedAd(this, "ca-app-pub-xxxxxxxxxxxxxxxx/xxxxxxxxxx");
//mInterstitialAd.setAdUnitId("ca-app-pub-3940256099942544/1033173712");
mInterstitialAd.loadAd(new AdRequest.Builder().build());
mInterstitialAd.setAdListener(new AdListener() {
#Override
public void onAdLoaded() {
if (mInterstitialAd.isLoaded()) {
mInterstitialAd.show();
} else {
Log.d("TAG", "The interstitial wasn't loaded yet.");
}
}
#Override
public void onAdClosed() {
Log.w(TAG, "Interstitial ad cloed ");
onInterstitialshowed();
}
});
}
public void loadRewardedAd(){
this.rewardedAd = new RewardedAd(this, "ca-app-pub-xxxxxxxxxxxxxxxx/xxxxxxxxxx");
//this.rewardedAd = new RewardedAd(this, "ca-app-pub-3940256099942544/5224354917");
RewardedAdLoadCallback callback = new RewardedAdLoadCallback(){
#Override
public void onRewardedAdFailedToLoad(int i) {
super.onRewardedAdFailedToLoad(i);
}
#Override
public void onRewardedAdLoaded() {
super.onRewardedAdLoaded();
showRewardedAd();
}
};
this.rewardedAd.loadAd(new AdRequest.Builder().build(), callback);
}
public void showRewardedAd(){
if(rewardedAd.isLoaded()){
RewardedAdCallback callback = new RewardedAdCallback() {
#Override
public void onUserEarnedReward(#NonNull RewardItem rewardItem) {
Log.w(TAG, "onUserEarnedReward");
}
#Override
public void onRewardedAdOpened() {
super.onRewardedAdOpened();
Log.w(TAG, "OnRewardAdOpened");
}
#Override
public void onRewardedAdClosed() {
super.onRewardedAdClosed();
onRewardedAdLoadedOnClick();
}
#Override
public void onRewardedAdFailedToShow(int i) {
super.onRewardedAdFailedToShow(i);
Log.w(TAG, "onRewardedAdFailedToShow");
}
};
this.rewardedAd.show(this, callback);
}else{
Log.i(TAG, "Ad not loaded");
}
}
I had the same problem with SDK ANDROID LEVEL 30. When I changed it to SDK ANDROID LEVEL 29 the ADS showed.
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?
I have set the device id of the phone I use for adMob testing as a const in my app. My testing device is not my day-to-day device.
Today I wanted to test a use case with a reward video and all of the sudden I get no fill or internal errors.
I took a look into the Log Cat and I saw that the device Id changed
By device Id I am referring to the one that comes in this log:
I/Ads: Use RequestConfiguration.Builder().setTestDeviceIds(Arrays.asList("THIS_ID_HERE") to get test ads on this device.
Why does it changed?
Is it because I uninstalled the prod version and installed a dev version of my app?
Does it happens randomly?
Can I prevent this behavior?
Device Id changes if you reset your phone. It may cause when you update your OS.
It does not change randomly.
Uninstalling prod version and installing a dev version should not change your device id(AFAIK).
As per google given try to use below credential for testing ads.In that case you will not need to add Device Id.
<!--Ad test credentials-->
<string name="admob_app_id">ca-app-pub-3940256099942544~3347511713</string>
<string name="banner_home_footer">ca-app-pub-3940256099942544/6300978111</string>
<string name="interstitial_full_screen">ca-app-pub-3940256099942544/1033173712</string>
<string name="rewarded_video">ca-app-pub-3940256099942544/5224354917</string>
<!--Ad live credentials-->
<string name="admob_app_id">add here your live app id</string>
<string name="banner_home_footer">add here your live footer id</string>
<string name="interstitial_full_screen">add here your live interstitial id</string>
<string name="rewarded_video">add here your live rewarded id</string>
Now use below function for shows testing ads.
//Banner Ads
private void loadBannerAds(AdView mAdView) {
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
mAdView.loadAd(adRequest);
}
//Interstitial Ads
private void loadInterstitialAds(final InterstitialAd mInterstitialAd) {
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
// Load ads into Interstitial Ads
mInterstitialAd.loadAd(adRequest);
mInterstitialAd.setAdListener(new AdListener() {
public void onAdLoaded() {
if (mInterstitialAd.isLoaded()) {
mInterstitialAd.show();
}
}
});
}
//RewardedVideo Ads
private void loadRewardedVideoAd(RewardedVideoAd mRewardedVideoAd) {
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
mRewardedVideoAd.loadAd(context.getResources().getString(R.string.rewarded_video), adRequest);
mRewardedVideoAd.setRewardedVideoAdListener(new RewardedVideoAdListener() {
#Override
public void onRewarded(RewardItem rewardItem) {
}
#Override
public void onRewardedVideoAdLeftApplication() {
}
#Override
public void onRewardedVideoAdClosed() {
}
#Override
public void onRewardedVideoAdFailedToLoad(int errorCode) {
}
#Override
public void onRewardedVideoCompleted() {
}
#Override
public void onRewardedVideoAdLoaded() {
try {
if (mRewardedVideoAd.isLoaded()) {
mRewardedVideoAd.show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onRewardedVideoAdOpened() {
}
#Override
public void onRewardedVideoStarted() {
}
});
// showing the ad to user
// make sure the ad is loaded completely before showing it
if (mRewardedVideoAd.isLoaded()) {
mRewardedVideoAd.show();
}
}
I hope this can help you!
I published my Application few days ago in Play Store, everything works perfectly, the Ads (Banner & Interstitial) were appearing as expected. But today, i discovered that the Interstitial Ads are appearing but not Banner ads. This is my first application and I don't know what may be the problem.
Sometimes ads are not shown due to lack of ads in google's ad inventory. You can check ad request response code to be sure.
mAdView.setAdListener(new AdListener() {
#Override
public void onAdLoaded() {
// Code to be executed when an ad finishes loading.
}
#Override
public void onAdFailedToLoad(int errorCode) {
// Code to be executed when an ad request fails.
Log.d("ADMOB_ERROR_CODE", "admob error code: " + errorCode);
}
#Override
public void onAdOpened() {
// Code to be executed when an ad opens an overlay that
// covers the screen.
}
#Override
public void onAdLeftApplication() {
// Code to be executed when the user has left the app.
}
#Override
public void onAdClosed() {
// Code to be executed when when the user is about to return
// to the app after tapping on an ad.
}
});
Further Reading: https://developers.google.com/admob/android/banner