When I display an Admob interstitial, it displays fine, and I have registered a listener to catch the onAdClosed event, but the problem is that I cannot actually do anything from that event that interacts with my UI because the interstitial has closed it all.
I'm creating the interstitial like this:
storyAd = new InterstitialAd(this);
storyAd.setAdUnitId("ca-app-pub-xxxxxxxxxxxxxxxx");
storyAd.setAdListener(new AdListener() {
#Override
public void onAdClosed() {
super.onAdClosed();
storyAd.loadAd(buildAdRequest());
if (prevMusicPlaying) {
toggleAudio();
}
loadNextPage();
}
});
storyAd.loadAd(buildAdRequest());
I have it in my manifest too:
<activity android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="#android:style/Theme.Translucent" />
The loadNextPage() call crashes because it tries to create a new fragment and add it to my activity, which it cannot do because the activity has been paused by the interstitial. So I just get this exception:
Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1328)
at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1346)
at android.app.FragmentManagerImpl.popBackStack(FragmentManager.java:488)
How can I make it so that the InterstitialAd doesn't interfere in any way with the existing UI. It took a very long time to get the existing UI working with the various activity/fragment gotchas.
You are probably finishing the current activity before you are showing the interstitial and then relying on the interstitial callback to move to next page or screen for that matter
This is bad practice since you don't want your app flow to rely on the ad callbacks. there can be scenarios which an ad cant show at all
What you need to do is call
loadNextPage();
before you show an ad. when the ad will show it will simply go over the the app screen that way if there is an ad it will simply take over otherwise it will not effect the app
So, the answer is less than ideal but it works.
You update your data model in onAdClosed() but not anything related to the UI. Set a flag to indicate that the ad is closed or whatever you need to do.
Then in onResume() on the main Activity, you update the UI. You can check the flag from onAdClosed() or whatever and then update the GUI to reflect the new state.
Related
My rewarded video is loading really really slow even for a video ad.
And sometimes it won't load at all.
My app:
I have a MainActivity (where I first init the MobileAd with my app ID).
And then you can go to the "get help" Activity where the rewarded video ad loads and you can watch it in exchange for clues.
I noticed that the video would load only once in the app lifetime. after that, and after go back to the main activity and then return to the "get help", the video won't load.
Like I said, the init of the mobile ads is in the onCreate() of the MainActivity.
in the GetHelpActivity there is an instance of RewardedVideoAd in the class and I am loading the ad in the onResume() of the class.
You can use simple loadAd() to reload rewarded ad.
inside
RewardedVideoAd mAd;
#Override
public void onAdClosed() {
super.onAdClosed();
mAd.loadAd();
}
https://developers.google.com/admob/android/rewarded-video-adapters
Use onRewardedVideoompleted.load ad in onRewardedVideoCompleted.onAdclosed will be only called when ad is closed(when user click X).hope it helps
I implemented admob interstitials into my app and everything is working fine.
Admobs interstitials are full screen and this is fine, the problem is that somehow when the admob interstitial is shown in full screen, my app (in the background) also jumps into full screen.
Now when someone closes the ad, the app jumps from full screen back to being normal again and this looks like a bug to me, because it causes a small flickering effect.
Did anyone else notice this effect, or I am alone in this?
Is there some way to fix this? Can i force my app to stay that way and not jump to full screen? Or can I force the status bar on interstitials ads?
Thank in advance!
Edit, my sourcecode is very similiar to this (standard approach taken from google itself):
public class BannerExample extends Activity {
private InterstitialAd interstitial;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Create the interstitial.
interstitial = new InterstitialAd(this);
interstitial.setAdUnitId(MY_AD_UNIT_ID);
// Create ad request.
AdRequest adRequest = new AdRequest.Builder().build();
// Begin loading your interstitial.
interstitial.loadAd(adRequest);
}
// Invoke displayInterstitial() when you are ready to display an interstitial.
public void displayInterstitial() {
if (interstitial.isLoaded()) {
interstitial.show();
}
}
}
update:
i integrated mopub which also offers full screen interstitials and interestingly enough this does not happen with mopub even though integrating it in the app is similar to admob. so i bet this is some odd behaviour of admob and not some bug in my app
It really depend on what is going on during Activity.onResume, when it call resume it try to update the view. It may look like flickering, but it just updating the view. Check your class and print some debug log to see what is it doing when you click the close button.
AdMob SDK don't control your class, so it only dismiss the ad view. What you do in your class cause the flickering. Without seeing the code, I cannot say for sure, maybe some code would be great.
Check my reply here:
Phonegap screen flickers with AdMob animation
Perhaps is a similar issue. Not every developer has the luxury of switching to a different provider (ie. if you work with a client)
I have an Android App which displays Interstitial Ads using Googles admob network. The good thing about admob is, its activity independent. I can load the ad in my MainActivity and whenever admob is ready with the ad, it will display it, even when I am not in MainActivity anymore. I already use the isLoaded() method to show the ad, and thats 90% of the time already working as desired.
But the other 10% it is not. There are certain activities which should remain adfree because the ad will decrease the quality of the game. If a phone is slow or the connection is slow and it takes a while to load an ad, the ad might pop up in the wrong activity.
Is there something I could call, which would close loaded ads and stops loading ads which are not displayed yet? This would take effect only on two activities whilst the others will remain as they are.
so in my main activity I call:
Ads.loadAdMobInterstitial(MainActivity.this);
and this is my class which handles Ads:
public class Ads {
public static InterstitialAd loadAdMobInterstitial(final Context context) {
int admobUnitId = string.admob_ad_unit_id;
final InterstitialAd iAd = new InterstitialAd(context);
iAd.setAdUnitId(context.getString(admobUnitId));
iAd.setAdListener(new AdListener() {
#Override
public void onAdLoaded() {
iAd.show();
}
});
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
iAd.loadAd(adRequest);
return iAd;
}
}
OK, first of all, you should NEVER call interstitialAd.show() from onAdLoaded(). As you have pointed out it will cause a poor user experience. It is also likely to get your Admob account banned.
I suspect that what you really want to do is to refactor your existing Activities into Fragments and host them all within your MainActivity. That way you will have the control you need to switch the interstitial on/off.
And make sure that you are showing your interstitial from a natural break point in your app rather than from onAdLoaded().
You can add a boolean flag in your onPause/onResume methods in the activity or fragment. Then check on adLoaded event like this:
interstitial.setAdListener(new AdListener() {
#Override
public void onAdLoaded() {
super.onAdLoaded();
if(!paused) {
interstitial.show();
}
}
});
Load your interstitial ad in background, but don't use onAdLoaded() method.
When you are at the point in the app, where you want to show your interstitial, use this:
if (admobInterstitial.isLoaded()) {
admobInterstitial.show();
}
This will show interstitial ad only in case it is loaded. Otherwise nothing will happen.
I noticed that my app was receiving few clicks on the InterstitialAd, and I saw that the Ad could be instantly closed by pressing the Back button. Usually the ad takes a few seconds to appear, so the user can close it even before seeing it (when only a black screen appears).
I don't think that it's fair, is almost useless to show it. Is there anyway to prevent this from happening?
I did this, but nothing happened...
// When creating the InterstitialAd, I set the following listener
mInterstitial.setAdListener(new AdListener() {
#Override
public void onAdLoaded() {
isShowingInterstitialAd = true;
mInterstitial.show();
}
#Override
public void onAdClosed() {
isShowingInterstitialAd = false;
mAdView.setVisibility(View.VISIBLE);
mAdViewClose.setVisibility(View.VISIBLE);
}
});
// On the Activity's class
#Override
public void onBackPressed() {
if (isShowingInterstitialAd) {
return;
}
// ...
}
My understanding is that AdMob draws its own Activity on top of yours, so it has its own implementation of onBackPressed(), which means that you don't have control of anything that happens once you call mInterstitial.show(); until AdMob gives control back to your activity.
Don't sweat the little things like this.
You are much better off spending energy making your app better.
Some people will never click on ads. But if you provide an inapp purchase that removes the ads they may well buy that. That is a better return on investment for your dev effort.
IMHO
Depending on your OS, there are a few ways to override that back button. Search for back button override to find them.
Does anyone know if any of the Android Advertising SDKs work with the new DreamService functionality? I tried using AdMob and first saw that the Interstitial class constructor explicitly requires an Activity. I saw the the AdView has a constructor that just needs a context so I tried that, but got a runtime exception telling me the problem was that I'm trying to inflate an AdView using a Context other than Activity. I looked into trying the Amazon Mobile Ads API, but it appears identical to the AdMob one.
I tried to get creative and start another Activity from my DreamService that creates an Interstitial ad, but it was created behind the DreamService UI (kinda makes sense since the Daydream overlays everything). Does anyone know of any solution to using Ads in a Daydream?
I came up with something that solves this issue, though I still don't really like the solution. Would welcome a more elegant approach if anyone knows of one.
What I did was use the mMedia SDK instead of AdMob. Their Interstitial and AdView classes can both take a Context rather than an Activity in the constructor. The Interstitial still didn't work out for me since it opens behind the Dream overlay. So what I ended up doing was adding an AdView to my Dream's XML layout, then setting its visibility to View.GONE until I wanted to display it. When it's time to display the ad I set it to View.VISIBLE.
The other issue I encountered was that after clicking the AdView it launches the browser with the ad's URL, which of course opens behind the Dream, defeating the purpose of showing an ad. So I ended up setting the Dream to be interactive, caught the onTouchEvent, then if the Ad is VISIBLE when the click happens call the Ad's callOnClick method. I also had to set the Ad's RequestListener to my Dream Service and implement the MMAdOverlayLaunched method, which is called when the Ad launches the browser. In this method I just called finish() to stop the Dream and let the browser display the Ad.
#Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
// Exit dream upon user touch
setInteractive(true);
// Hide system UI
setFullscreen(true);
// Set the dream layout
setContentView(R.layout.dream_layout);
//Initialize Ads
this.initAdvertising();
}
private void initAdvertising(){
MMSDK.initialize(this);
mDreamAd = (MMAdView) findViewById(R.id.adView);
//Separate thread will handle showing the ad
mDreamAd.setVisibility(View.GONE);
mAdRequest = new MMRequest();
//TODO add metadata to Request
mDreamAd.setMMRequest(mAdRequest);
mDreamAd.setListener(this);
mDreamAd.getAd();
}
#Override
public boolean dispatchTouchEvent(MotionEvent event){
super.dispatchTouchEvent(event);
if(mDreamAd != null && mDreamAd.isShown()){
mDreamAd.callOnClick();
}
return true;
}
#Override
public void MMAdOverlayLaunched(MMAd ad) {
//Finish so we can display the ad the user has clicked
if(ad.equals(this.mDreamAd))
this.finish();
}