Disabling AdMob Ads in certain parts of app - java

My App, (OpenGL ES 2.0) currently has 55 classes, and one activity single.
I have my own custom Scene Manager which I use to change between different Scenes (ie, different scenes would be: Main Menu, Level Select, Level 1, Level 2....Level 20, Game Over etc...)
So I set all of my AdMob stuff up in my Activity's onCreate(); method. So at the moment, the same ad runs throughout the whole app.
How it is possible to 'switch off' the ads on different Scenes?
Bear in mind that none of my classes have direct access to the Activity class itself.
Any suggestions would be appreciated as I'm finding using AdMob extremely challenging, it doesn't seem very intuitive so any AdMob experts out there, your opinions would be appreciated!
I should point out that I don't use XML, everything is done programmatically.
Thanks
Code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create an ad.
adView = new AdView(this);
adView.setAdSize(AdSize.BANNER);
adView.setAdUnitId(AD_UNIT_ID);
// Add the AdView to the view hierarchy. The view will have no size
// until the ad is loaded.
RelativeLayout layout = new RelativeLayout(this);
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
// Create an ad request. Check logcat output for the hashed device ID to
// get test ads on a physical device.
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(TestDeviceID)
.build();
// Start loading the ad in the background.
adView.loadAd(adRequest);
//Request full screen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
//Create a displayMetrics object to get pixel width and height
metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
width = metrics.widthPixels;
height = metrics.heightPixels;
//Work out values for resizing screen while keeping aspect ratio
width = (int) Math.min(width, height * 1.702127659574468);
height = (int) Math.min(height, width / 1.702127659574468);
//Create and set GL view (OpenGL View)
myView = new MyGLSurfaceView(MainActivity.this);
RelativeLayout.LayoutParams adParams =
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
adParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
adParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
//Set the colour if we don't, the ad won't show (bug?)
adView.setBackgroundColor(Color.BLACK);
layout.addView(myView);
layout.addView(adView, adParams);
//Create a copy of the Bundle
if (savedInstanceState != null){
newBundle = new Bundle(savedInstanceState);
}
setContentView(layout);
}

First of all you're causing yourself a lot of pain by doing your layout programmatically (I gave a talk on this just last night). You should really consider understanding and using the XML layout.
But to answer your question, you will need to find a way for the classes that want to control whether an ad is shown or not to have some method of sending a message to the Activity. I would suggest injecting them with an interface that is implemented by an inner classes in your Activity.
The interface is going to need to look something like:
- startShowingAds - this should start requesting ads and make the AdView visible.
- stopShowingAds - this should pause ad showing and hide the AdView.

To temporarily hide the ads you just need to hide the AdView, eventually calling pause() even though I think that hidden ad views are not refreshed (you can check in the logs).
About how to reach the AdView object from your code, it depends on what you have accessible from there. If you just have the View where you are drawing a solution could be to store the AdView object in the View's tag (see setTag() and getTag() here: https://developer.android.com/reference/android/view/View.html#getTag%28int%29).

Related

Create an overlay window in android 19

I'm trying to create an overlay window in android (a which will float over any other app in the screen, even when my app is on background)
I followed several guides (some from SO) and here is the important code
this.sp = PreferenceManager.getDefaultSharedPreferences(context);
this.wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
this.main = (FrameLayout) LayoutInflater.from(c).inflate(R.layout.ui_floating_window, null);
int type = WindowManager.LayoutParams.TYPE_TOAST;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O)
type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
Point p = new Point();
wm.getDefaultDisplay().getSize(p);
this.displayHeight = p.y;
this.displayWidth = p.x;
this.rationWH = this.displayWidth / (float) this.displayHeight;
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
sp.getInt(Constants.DefaultSharedPreferences.FLOATING_WINDOW_WIDTH, this.displayWidth / 2),
sp.getInt(Constants.DefaultSharedPreferences.FLOATING_WINDOW_HEIGHT, this.displayHeight / 2),
sp.getInt(Constants.DefaultSharedPreferences.FLOATING_WINDOW_X, this.displayWidth / 2),
sp.getInt(Constants.DefaultSharedPreferences.FLOATING_WINDOW_Y, this.displayHeight / 2),
type,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.START | Gravity.TOP;
params.horizontalMargin = 0;
params.verticalMargin = 0;
this.wm.addView(main, params);
i've tested on android 29 and works really fine
but on android 19 the window opens but as soon as the current app goes background the window goes either. i would like the window stayed on even after user switches the app.
This is how i get 19
this is how it works in android 29 (correct way)
https://i.imgur.com/JjMugfG.mp4
am i doing anything wrong
The problem is that the WindowManager instance from Activity is different than the instance retrieved from the application-level Context.
Let's try a test:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context context = this; // context of the activity
WindowManager wm1 = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
WindowManager wm2 = (WindowManager) context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
System.out.println("Are equal? " + wm1.equals(wm2));
}
The result is FALSE.
Actually, a WindowManager is responsible for managing a list of windows on the screen. In the case of Activities, when the Activity gets disappeared, all of the related windows such as your added floating view would be gone. While your app lives in the background after pressing the home button, for instance, its window manager (Application's window manager) keeps all of the managed windows. It means that your floating view has the chance of being shown until the app would be killed by the system.
So, by retrieving WindowManager instance from application-level Context and adding the view to it, the problem will be solved.
For 7 years, I work on Floating Apps (https://floatingapps.net) which is basically a set of floating mini-apps, so I know something about it :-).
I first get it working on Android 2.3.5 and progress until today.
It's a complex problem if you want to do it right across all possible devices and Android versions.
I recently published a series of articles on this topic. Check it out: https://localazy.com/blog/floating-windows-on-android-1-jetpack-compose-and-room
It goes from the main app, background service, permissions, floating windows, moving them, keyboard input to the list of tips, trick and shortcomings I learned along the way.
It should learn you how to do it right.
The window manager you are getting from an activity points out to Activity.getWindow() when adding a view, which naturally disappears if you click the back button or home button. That means you need another decor view to resolve your problem, which is calling the application context in your case, where it will let you manage the phone's window, as you want.
Check application context, and if it's not null, get the WindowManager instance, then try adding your view.
Also I'm not sure but using WindowManager.TYPE_SYSTEM_ALERT also might help.

How to control google play leaderboard log in

I followed a tutorial in connecting to google leaderboard but a lot of tutorials are using the old google play services library. I manage to sign in to google using this code but it appears upon starting the app. Where should I put the googleAPIclient code so that I can log in when I click a button inside the game. I use libgdx and if anyone can link a tutorial that uses a new google play services library It would help a lot. I seemed to be stuck with this one. Thank you!
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create the layout
RelativeLayout layout = new RelativeLayout(this);
// Do the stuff that initialize() would do for you
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
// Create the libgdx View
View gameView = initializeForView(new RBGame(this,this), false);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Plus.API)
.addApi(Games.API)
.addScope(Plus.SCOPE_PLUS_LOGIN)
.addScope(Games.SCOPE_GAMES)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
// Create and setup the AdMob view
adView = new AdView(this);
adView.setAdSize(AdSize.BANNER);
adView.setAdUnitId(AD_UNIT_ID);
AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);
// Add the libgdx view
layout.addView(gameView);
// Add the AdMob view
RelativeLayout.LayoutParams adParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
adParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
adParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
//layout.addView(adView, adParams);
// Hook it all up
setContentView(layout);
}
Easiest way to get it going is to use BaseGameUtils which you can download here (it is located in /BasicSamples/libraries/).
The Google Play Game Services documentation describes how to use it. You still don't have to use BaseGameUtils, you could just use it as a reference for coding your own. But using it seems to be the way Google wants it done - probably to provide some consistency across games :)
Personally, I don't like using the BaseGameActivity as a base for my own activities and allowing it to take over the sign-in flow completely. I just use the GameHelper class to perform the required functionality on demand.

Adding a LinearLayout on top of Cocos2dxGLSurfaceView

I'm trying to make a VideoView work on top of the cocos2d-x surface view. I am now able to load and play a video using the following snippets of code:
When Initializing the class:
// Create the LinearLayout that will contain our VideoView
_videoLayout = new LinearLayout( _activity );
_videoLayout.setId( VIDEO_VIEW_ID );
_videoLayout.setGravity( Gravity.CENTER );
_videoLayout.setBackgroundColor( Color.BLACK );
_videoLayout.setOrientation( LinearLayout.VERTICAL );
_videoLayout.bringToFront();
// Add the LinearLayout to the current Activity
_activity = MyGame.getCocosActivity();
_activity.addContentView( _videoLayout, new LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT ) );
When playing a video:
// When the video is ready to be played, create a VideoView
VideoView videoView = new VideoView( Cocos2dxActivity.getContext() );
videoView.setLayoutParams( new LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT ) );
// Add it to the _videoLayout object
LinearLayout layout = ( LinearLayout ) activity.findViewById( VIDEO_VIEW_ID );
layout.setVisibility( View.VISIBLE );
layout.addView( videoView );
// Play the video
videoView.setVideoURI( Uri.parse( path ) );
videoView.requestFocus();
videoView.start();
The above code yields the following results:
The video is played and sounds are properly heard.
The video is centered both horizontally and vertically.
Sometimes, the video is played below the current Cocos2d-x view. Playing it again will make it be played on top of it.
The video is not full screen. It only covers enough space in the screen to show the video.
What my expected results are:
The video is played on top of the cocos2d-x view, at all times.
The video takes up the whole screen, still maintaining aspect ratio, but has black borders on the sides.
I can't seem to figure out how to accomplish these two. Any help? I'm not very experienced with the Android Framework so please bear with me.
NOTE: I don't want to use XML to create layouts.
Why don't you want to use XML layouts? They are designed for this, and amke your life much easier after you get a hang of them.
Anyhow : in my case I added my VideoView on a RelativeLayout and set its CenterHorizontal and CenterVertical parameters to true. The width and height is set to wrap_content. This was done in XML, so I cannot provide you with Java equivalent.
Also try calling bringToFront() on your layout to ensure that the video is on top of CocosView.

Android Admob showing blank RocketFuel ads often

I have a working AdMob AdView on top of my opengl game. Its working great but I notice that it keeps showing a particular blank ad. I thought it was a bug on my side but then I noticed that the ad is functioning partially. The ad appears to be a RocketFuel ad according to the provided info button in the top right of the AdView. Clicking within the blank AdView area does nothing unless the info button it hit. The images and code below help explain.
I thought RocketFuel was a separate ad service, is it possible to limit its appearance in Google AdMob using the Filter Settings > Category / Type Settings > Affiliate offers? Or perhaps one of the other categories? I am going to try adding a URL Block for rocketfuel.com under the Ad Filters. However I am unsure if they are serving ads directly from their domain.
Otherwise, is there any way to block, report, or limit these types of ads from being shown through my app? Has anyone had similar problems with such ads?
Here is how I slap the adview on top of my java based OpenGL ES 2 renderer:
#Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mView = new nopgRenderer(this);
setContentView(mView);
adView = new AdView(this, AdSize.IAB_LEADERBOARD, "<AdMobAdAppID>");
RelativeLayout layout = new RelativeLayout(this);
layout.addView(adView);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
params.addRule(RelativeLayout.CENTER_HORIZONTAL);
adView.setLayoutParams(params);
this.addContentView(layout, params);
adView.loadAd(new AdRequest());
}
public static void hideAd(){
adView.setVisibility(AdView.GONE);
}
public static void showAd(){
adView.setVisibility(AdView.VISIBLE);
}
The app on Google Play:
https://play.google.com/store/apps/details?id=com.dmtsource.nopg
Example of a normal ad:
Example of the blank ad:
Clicking on the info item in the blank ad:

Android Java memory usage with AdMob

I am experience som major memory issues with my projekt. If you could throw some advice for me that would be really helpfull.. I'll try to explain my whole usage.
In the main activity, the first thing I do is setting upp the AdMob banners. Which seems to use ALOT of memory. This is my whole onCreate method:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
mGameView = new GameView(this, getAssets());
ActivityManager am = ((ActivityManager)getSystemService(Activity.ACTIVITY_SERVICE));
mGameView.setMemoryLimit(am.getMemoryClass());
mLayout = new RelativeLayout(this);
mLayout.addView(mGameView);
if(mGameView.getMemoryLimit() > 40 && !mGameView.isFullVersion())
{
mAdView = new AdView(mThis, AdSize.BANNER, "xxxx");
mAdRequest = new AdRequest();
mAdView.loadAd(mAdRequest);
mAdRequest = null;
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
lp.addRule(RelativeLayout.CENTER_HORIZONTAL);
mAdView.setLayoutParams(lp);
mLayout.addView(mAdView);
}
setContentView(mLayout);
hideBannerAd();
}
As I have googled alot, the AdMob code seems to leak memory so I try to keep it alive the whole lifetime of the app and only showing it on loadingscreens.
At this point I am using maybe 10-15mb memory JUST FOR THE ADS.
I have grouped all bitmaps used by Menu and Gameplay. Which means I only load the the menu bitmaps when I show the menu and then recycle and delete the reference of the old bitmaps before loading the new ones.
During the loading process I check how much percent of memory I have left and only continue to load bitmaps if the percent is less than 90%.
I calculate the memory percent by:
Debug.getMemoryInfo(memoryInfo);
percent = (float) (memoryInfo.getTotalPss() / 1024.0) / (float) mGameView.getMemoryLimit() * 100;
tge memoryLimit comes from earlier mentioned activity:
ActivityManager am = ((ActivityManager)getSystemService(Activity.ACTIVITY_SERVICE));
mGameView.setMemoryLimit(am.getMemoryClass());
As you saw in the activity I am only showing ads for devices with more than 40mb memory. But I am using about 20mb for the project WITHOUT ADS.
Another problem I have encountered is with devices that share memory with other applications. Like if their memory limit is 64 but is still using like 40-50 from elsewhere than my app. Can I somehow request that memory to be cleared?
Am I doing someting wrong because this is really getting to my nerves. I mean I have seen apps using like 2-5 ads at the same time..
Can I somehow manage this better?

Categories

Resources