Просмотр исходного кода

Android: hide system bars via WindowInsetsController on API 30+

The immersive-fullscreen code hid the status and navigation bars with the
deprecated View.setSystemUiVisibility() flags plus FLAG_FULLSCREEN. On
Android 15+ (API 35), edge-to-edge is enforced for apps targeting SDK 35+
and those flags are ignored, so the bars never hide (e.g. on a Samsung
S25). Android 14 and below still honour them, which is why older devices
were unaffected.

Hide/show the system bars with WindowInsetsController on API 30+ (using
BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE for sticky-immersive), keeping the
legacy setSystemUiVisibility() path for API < 30. The minimum supported
version is unchanged.

(cherry picked from commit a442367706d1bde3b29232a351e62f749559560d)
klirktag 21 часов назад
Родитель
Сommit
5317703567
1 измененных файлов с 43 добавлено и 17 удалено
  1. 43 17
      android-project/app/src/main/java/org/libsdl/app/SDLActivity.java

+ 43 - 17
android-project/app/src/main/java/org/libsdl/app/SDLActivity.java

@@ -39,6 +39,8 @@ import android.view.Surface;
 import android.view.View;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewGroup;
 import android.view.Window;
 import android.view.Window;
+import android.view.WindowInsets;
+import android.view.WindowInsetsController;
 import android.view.WindowManager;
 import android.view.WindowManager;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.InputMethodManager;
@@ -952,15 +954,31 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
                     Window window = ((Activity) context).getWindow();
                     Window window = ((Activity) context).getWindow();
                     if (window != null) {
                     if (window != null) {
                         if ((msg.obj instanceof Integer) && ((Integer) msg.obj != 0)) {
                         if ((msg.obj instanceof Integer) && ((Integer) msg.obj != 0)) {
-                            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;
-                            window.getDecorView().setSystemUiVisibility(flags);
-                            window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
-                            window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+                            if (Build.VERSION.SDK_INT >= 30 /* Android 11 (R) */) {
+                                // The legacy setSystemUiVisibility() flags are ignored on
+                                // Android 15+ (API 35+), where edge-to-edge is enforced for
+                                // apps targeting that SDK, so the status/navigation bars
+                                // would never hide. Use WindowInsetsController instead.
+                                window.setDecorFitsSystemWindows(false);
+                                final WindowInsetsController controller = window.getInsetsController();
+                                if (controller != null) {
+                                    controller.hide(WindowInsets.Type.systemBars());
+                                    // Sticky-immersive (replaces SYSTEM_UI_FLAG_IMMERSIVE_STICKY):
+                                    // a swipe shows the bars transiently, then they auto-hide.
+                                    controller.setSystemBarsBehavior(
+                                            WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
+                                }
+                            } else {
+                                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;
+                                window.getDecorView().setSystemUiVisibility(flags);
+                                window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+                                window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+                            }
                             SDLActivity.mFullscreenModeActive = true;
                             SDLActivity.mFullscreenModeActive = true;
                         } else {
                         } else {
                             int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_VISIBLE;
                             int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_VISIBLE;
@@ -1799,14 +1817,22 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
     private final Runnable rehideSystemUi = new Runnable() {
     private final Runnable rehideSystemUi = new Runnable() {
         @Override
         @Override
         public void run() {
         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);
+            if (Build.VERSION.SDK_INT >= 30 /* Android 11 (R) */) {
+                final WindowInsetsController controller =
+                        SDLActivity.this.getWindow().getInsetsController();
+                if (controller != null) {
+                    controller.hide(WindowInsets.Type.systemBars());
+                }
+            } else {
+                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);
+            }
         }
         }
     };
     };