i want to add admob advertising to my game app. however the game drawing is all on in code with no layouts, just the Surfaceview the game draws on.
I cannot use the
layout.addView(adView);
the docs give as an example since my game uses no layout, in fact the layout folder is deleted.
in the main activity I define a game panel:
gamepanel=new MainGamePanel(this);
the gamepanel is instantiated:
class MainGamePanel extends SurfaceView implements SurfaceHolder.Callback
and then I just draw right to the surfaceview using Canvas draw methods.
so how do I add the adView object I created in the activity to the surfaceview:
adView = new AdView(this, AdSize.BANNER, "MY_PUU_NUMBER");
gamepanel.addView(adView) does not work. maybe i'll be forced to use a layout from the start just for this, but that will complicate things.
The best workaround I've found for adding admob advertising to a surfaceView application is to create a layout programmatically and draw both views to it as follows:
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
ll.addView(adView); // The ad banner
ll.addView(gamepanel); // The SurfaceView object
It's not actually drawing the adView to the surfaceView, but it's the best way I've found to include it.
Note that a banner ad will slow your framerate so be judicious. Unfortunately nowadays it's hard to get android game players to shell out even .99 upfront for a game if your company's name isn't Square Enix, so ads can be a necessary evil.
I am trying to show a dynamic OpenGL over the Android camera preview. I have used the typical framework suggested in other guides/sites to create an object which implements the GLSurfaceView.Renderer interface and use setContentView() and addContentView() after. The problem is that the onDrawImage is occurring behind the surface holder which displays the camera preview.
This is part of a larger application and I have separately tested all components in a side application. The only difference between the two is that the larger application has several activities preceding this one, while the side application uses just this activity as the main one.
Update
The answer is to switch the order of the setContentView and addContentView. If it is the main application, use the order in this post: opengl overlay on camera view; however, if you are coming from another activity, run:
setContentView(theCameraCallbackView)
addContentView(theOpenGLView, new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT ))
If anyone can provide some reasoning behind this, it would be greatly appreciated! I spend about eight hours on this two-line swap so it would be great to know what the cause of this was (and hopefully prevent similar issues for others).
I need to create a game for one of my projects. The game is not a grafic game but I still want it to have nice appearance (maybe 3D background look).
I thought I would use a diferent technique than just to load the background through an xml file. I want to create a surface view with a nice texture background (what I would like is one similar to the live wall papers). I know there is the rendererscript but I apparently it doesn't work on apis level lower than 11??? I would like to target api level 7 or 8.
Here is what I planned to do something like that:
mView = new BasicGLSurfaceView(getApplication());
View inflatedView=View.inflate(this, R.layout.title, null);
View inflatedView2=View.inflate(this, R.layout.buttons, null);
setContentView(mView);
this.getWindow().addContentView(inflatedView,
new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
this.getWindow().addContentView(inflatedView2,
new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
I was wondering which way is the best:
use open GLSurfaceView or just normal SurfaceView and Canvas. Which one is faster and will look nicer?
Could you please advice me on the best solution to implement?
thank you
Canvas is simpler, and it's fast, but it doesn't support 3D drawing. Since you said that you might want to do 3D, you would want to use the GLSurfaceView and OGLES. Canvas can often outperform OpenGL for 2D drawing.
We've been fighting with some problems relating to SurfaceViews for more than a week, and find no proper solution to them. We read the other questions in the forum regarding to similar problems (and even Mixare source code) but couldn't find an answer, so we hope you could help us somehow.
Scenario:
We've got
a SurfaceView for the Camera
a SurfaceView for an OpenGL layer, which goes on top of the camera.
another View, which shows some information about what we can see on the screen. This one goes on top of both SurfaceViews.
Problem:
No matter how hard we try, both SurfaceViews apparently don't get on well with each other. If we try to:
setContentView(mCameraPreview);
addContentView(mGLSurfaceView, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
addContentView(mInfoView, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
(which seems logical), everything goes as expected until we lock/unlock the phone. After that, the GLSurfaceView just disappears (not the InfoView, that one is still shown).
If, instead, we try to:
setContentView(mGLSurfaceView);
addContentView(mCameraPreview, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
addContentView(mInfoView, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
Then the problem is that the GLSurfaceView only appears after lock/unlock, and before that the screen is showing the camera and the InfoView.
We discovered that if we sleep the main thread for 4.6 seconds (or more) after executing onStart() in the activity that shows the views, the behaviour is as expected (both camera, glsurface and info views are shown, even after lock/unlock).
The thing is, we're looking for a more... elegant solution.
It seems to us that the problem is the camera taking more time than expected in Camera.open(), and so the camera View is added, the GLSurfaceView is added, and when the camera actually opens, it opens on top of the GLSurfaceView. Regarding to this, we used bringToFront() on GLSurfaceView, and got it on top of the info view, but after lock/unlock the camera still opened on top of it, leaving us with a screen with the camera preview only.
Any ideas? How can we show both SurfaceViews and the info view on top of them?
try this:
mLayout.addView(mRenderView);
mLayout.addView(mCustomSurfaceView);
// without this line, the camera preview cannot be displayed
// when running activity at first time.
mCustomSurfaceView.setZOrderMediaOverlay(true);
this worked for me :)
I had the same problem. As you hint at yourself: multiple SurfaceViews don't get along with each other in that their Z order is undefined.
On my Samsung Galaxy S2 the ordering is the same as you describe (don't know how it is on other phones).
The way I solved this, is checking for first time creation of the Activity in onCreate():
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//...
if ( savedInstanceState == null )
{
initCamView();
initOpenGL();
}
else
{
initOpenGL();
initCamView();
}
//...
}
with:
private void initOpenGL()
{
mGLSurfaceView = new GLSurfaceView(this);
mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
mGLSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
mOGLRenderer = new OGLRenderer(this);
mGLSurfaceView.setRenderer(mOGLRenderer);
mRL.addView(mGLSurfaceView); // mRL is the Relative Layout
}
and:
private void initCamView()
{
mCamView = new CustomCameraView( this.getApplicationContext(),
this.getWindowManager() );
mRL.addView(mCamView); // mRL is the Relative Layout
}
Not the most elegant solution, but it's better than letting the thread sleep for 4.6 seconds.
It might also be possible to just lock the screen in a single orientation, but then you need to do a lot of ugly hacking to get the overlays rotated the right way.
Or, if you're only targeting Android 3.0 or above (API level 8), you can just show the camera in an OpenGL SurfaceTexture. http://developer.android.com/reference/android/hardware/Camera.html#setPreviewTexture(android.graphics.SurfaceTexture)
Each SurfaceView's surface has a Z-depth. There are three possible depths: the default (bottom), "media overlay" (above it), and "top" (which is above everything, including the View-based UI). If you have two overlapping surfaces at the same depth, one will win, but you can't reliably define which one. You might get consistent behavior on one device only to find that it works the other way on a different device.
The composition is done with hardware overlays, when possible. Many currently-popular devices have 4 overlay planes. Once you exceed that, the composition is done with the GPU, which is going to be more expensive. If you have a status bar, navigation bar, and View UI, that's three, so you only get one SurfaceView for cheap.
For the example in the question, it would be best to combine as many things as possible onto the surface being rendered with GLES. This can include camera output on API 11+. See the "Texture from Camera" activity in Grafika for an example. (Grafika also has a demo app with three overlapping SurfaceViews; see the "multi-surface test" activity.)
If you'd like to know more about why SurfaceView behaves the way it does, see the Android System-Level Graphics doc.
I had the same problem: I wanted a SurfaceView under a GLSurfaceView, the first to play video and the second to run a game.
Whatever I did, the z order between these 2 surface views appears to be random.
But I found the solution, thanks to this post: https://stackoverflow.com/a/6028907/1557915
The trick is to remove the use of layout, but instead use setContentView/addContentView.
I am currently attempting to animate some images in my SurfaceView. Right now, I am displaying my images as Bitmaps. However, I think it might be better to implement these Bitmaps as ImageViews. I have not been able to create multiple ImageViews on my SurfaceView (I am trying to not do this in XML, as I want to get things working first and then later change things around so it is more portable). Is there a tutorial somewhere on how to do this, or am I like wayyy off and should just stick to Bitmaps??
You generally shouldn't try to mix View objects and SurfaceView. SurfaceView is a very special view that provides direct drawing by essentially punching a hole in the current window. It seems better to stick to bitmaps.