Android Devices - Screen Best Practices - Virtual Buttons & In-Screen Cameras?


How do we properly use the Android device screen
when there are virtual buttons on the bottom
and an in-screen camera on top?

Let us know, thanks!


1 Like

I’m really interested in this too. I just released an update to one of my Android games ‘Kozui’ with the latest SDL (2.0.12) and it uses:


but this seems to make the first render appear on the screen, and then something takes over and the whole screen goes black and it draws the status bar at the top, which then scrolls off upwards (this didn’t happen when I used SDL 2.0.8) and then my game’s next render makes my game appear OK . But after that, everything seems to work OK then with the game using the entire screen - except I’ve had a bug report from a user with a Realme 6 Pro (using Android 10) which has the game drawn offset down the screen (see screenshot) and screen taps are therefore sent with an inaccurate position to my game making it unplayable.

I’ve tried not including the SDL_WINDOW_FULLSCREEN flag and that seems to leave the status bar and buttons at the bottom showing, not sure if that fixes the bug on the Realme 6 Pro though.

This is the screenshot from a Realme 6 Pro with a black area at the top pushing my game down:

you may need to change SDL fullscreen behavior, commenting out:


Thanks Sylvain, I’m a bit wary on commenting out those two lines as I’m not sure what effect that would have on other devices, and I don’t have a Realme 6 Pro to test it on. Have you had this same problem, and does commenting out both those lines fix it (and not cause other problems)?

It sets the immersive mode and hide navigation bar. But last time i try, there was some issue for me and others with older android versions. Also size wasn’t always correct because the full-screen isn’t immediate. There are a few bugs entries in bugzilla, but I’m not sure if this can be really fixed.

You can safely comment it out if you don’t handle it perfectly.
Just make sure you don’t use calls to toggle in full-screen mode. And test on few devices…

See how SDL behaves by looking at COMMAND_CHANGE_WINDOW_STYLE

I’ve got some feedback from friends and SDL seems to work on:

Nexus 5X API 27(emulator)
Pixel 2XL API 27 (emulator)
Samsung Note 8
iGET G81H Android 7.0

but doesn’t work on:

Samsung S10
iGET blackview A30 Android 8.1
Realme 6 PRO

I guess this means that the current SDL (2.0.12) is broken on Android as it stands?

Here’s exactly what I remove from my code, I think this works fine but there is more than the two lines.

+++ app/src/main/java/org/libsdl/app/
@@ -269,10 +269,7 @@
-        setWindowStyle(false);
-        getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(this);
         // Get filename from "Open with" of another application
         Intent intent = getIntent();
         if (intent != null && intent.getData() != null) {
@@ -823,7 +820,6 @@
     public static void setWindowStyle(boolean fullscreen) {
         // Called from SDLMain() thread and can't directly affect the view
-        mSingleton.sendCommand(COMMAND_CHANGE_WINDOW_STYLE, fullscreen ? 1 : 0);
@@ -1433,30 +1429,7 @@
         return dialog;
-    private final Runnable rehideSystemUi = new Runnable() {
-        @Override
-        public void run() {
-            int flags = View.SYSTEM_UI_FLAG_FULLSCREEN |
-                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
-                        View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
-                        View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
-                        View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
-                        View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.INVISIBLE;
-            SDLActivity.this.getWindow().getDecorView().setSystemUiVisibility(flags);
-        }
-    };
     public void onSystemUiVisibilityChange(int visibility) {
-        if (SDLActivity.mFullscreenModeActive && ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0 || (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0)) {
-            Handler handler = getWindow().getDecorView().getHandler();
-            if (handler != null) {
-                handler.removeCallbacks(rehideSystemUi); // Prevent a hide loop.
-                handler.postDelayed(rehideSystemUi, 2000);
-            }
-        }
@@ -1771,22 +1744,7 @@
         mHeight = height;
         int nDeviceWidth = width;
         int nDeviceHeight = height;
-        try
-        {
-            if (Build.VERSION.SDK_INT >= 17) {
-                android.util.DisplayMetrics realMetrics = new android.util.DisplayMetrics();
-                mDisplay.getRealMetrics( realMetrics );
-                nDeviceWidth = realMetrics.widthPixels;
-                nDeviceHeight = realMetrics.heightPixels;
-            }
-        }
-        catch ( java.lang.Throwable throwable ) {}
-        synchronized(SDLActivity.getContext()) {
-            // In case we're waiting on a size change after going fullscreen, send a notification.
-            SDLActivity.getContext().notifyAll();
-        }
         Log.v("SDL", "Window size: " + width + "x" + height);
         Log.v("SDL", "Device size: " + nDeviceWidth + "x" + nDeviceHeight);
         SDLActivity.nativeSetScreenResolution(width, height, nDeviceWidth, nDeviceHeight, sdlFormat, mDisplay.getRefreshRate());

Maybe the last block is relevant (“nDeviceWidth” set by getRealMetrics()). It matters if you don’t handle the SDL resize event.

Thanks again Sylvain, I’ve updated my as you’ve suggested and sent off an update so I’ll see what feedback I get. I noticed that with your changes I still get the screen goes to black after my initial render draws my splash screen, and now on the emulator the 3 Android buttons (back, home, etc…) are now displayed at the bottom even though I’m creating the window with SDL_WINDOW_FULLSCREEN. That’s no deal breaker though.

BTW could the Android SDKs I’m specifying make any difference? I’m using:

android {
    compileSdkVersion 28

    defaultConfig {
        applicationId "com.windowsgames.kozui"
        minSdkVersion 16
        targetSdkVersion 28

I don’t think this make any difference but I use:
compileSdkVersion 29
targetSdkVersion 29
with ndk-r21d
I answered the SplashScreen in your other topic :slight_smile:

I found that some code I’d been recommended to add that solved weird colour issues on some Android phones like the Galaxy S9 was causing the problem I was having where I could render a screen, but then the screen would go completely black for a few seconds:

SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);

I was calling this code immediately before I called SDL_CreateWindow, and now that I’ve removed those lines I no longer get the black screen problem.

Would you still recommend I make the changes to as you’d outlined earlier? When I make your changes then the two emulators I use show the three Android buttons at the bottom of the screen, but I think in the past when I was on SDL2.0.8 those buttons were covered over. I’m not sure which behaviour Android users prefer TBH?

Yes there was strange colors issues. I’ve being using this for a while:

SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);

And it seems to work fine.

Yes, I think the change in are better if you don’t want, nor need to set the fullscreen.
And since you’re not in full-screen, you’ll see the three soft buttons on phones (only when they don’t have real buttons).

Is it a better behavior: some prefers and some other doesn’t. But it’s important to provide something not broken. Also:
-it may depends on you game. if it really needs full space or not.
-newer phones have high aspect ratio (almost 2.3), even if you remove the notch camera, and add the soft button, you still have something comfortable.

The best maybe is to add a setting in the game to let the user choose.

I’ve been playing around some more and I’ve found that if I call those SDL_GL_SetAttribute commands before I call SDL_CreateWindow then I have the black screen problem. But when I move them to after SDL_CreateWindow there’s no black screen. I guess you were always calling them after?

I’ll leave those commands in and make all the changes that you recommended to, and I’ll keep the flag SDL_WINDOW_FULLSCREEN, and release that and I’ll report back what my testers say when it goes live.

SDL_GL_SetAttribute commands need to be set before SDL_CreateWindow (and before create the GL context), otherwise they have no effect.

I see what’s happening:
The java SDLSurfaceView holder is configured for 565 by default. So when you request an 888 with the GL attributes, the surfaceView gets destroyed and re-created. (you should see with adb log cat: surface_destroyed/create or maybe only surface_change )… probably the black glitch.

The SDLSurfaceView is created before the SDLWindow and you can change the default format to match your app. See

( or getHolder().setFormat(PixelFormat.RGBX_8888 ?)

I don’t this format has any real effect except than putting extra warning in the log when there is a mismatch …
To check that, you could temporary comment:

Thanks yet again Sylvain! I think what I’ll do is just remove those SDL_GL_SetAttribute commands then, maybe that problem with colours on Samsung 9s is fixed now anyway?

I suggest, you use exactly :
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
I’m using this for years and has no problem. And it fixes issues with older phones (Samsung 3, some LG also). I didn’t get any wrong color reports with that.

I am using the SDL_Renderer. Not sure if you use your own GLES2 renderer.

Hi Sylvain, do you know if SDL 2.0.14 solves all these problems with Android screen problems? Did all of your mods to get added?

I haven’t got a new Android phone to test it on unfortunately so I’d be very grateful if you could let me know!

Hi Sean,
No. this is not solved in SDL 2.0.14. SDL needs the full-screen mode on the other side !
But, yes, we should make this somehow configurable …
not sure what is the best way: sub-classing some SDLActivity method ? Add some constant in SDLActivity ? we can also put some env in AndroidManifest.xml ?