using System; using System.Collections.Generic; using UnityEngine; class AndroidStatusBar { // Enums public enum States { Unknown, Visible, VisibleOverContent, TranslucentOverContent, Hidden, } // Constants private const uint DEFAULT_BACKGROUND_COLOR = 0xff000000; #if UNITY_ANDROID // Android flags for API 21+ (Android 5.0+) and newer private const int VIEW_SYSTEM_UI_FLAG_LOW_PROFILE = 1; // Added in API 14 (Android 4.0.x) private const int VIEW_SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 1024; // Added in API 16 (Android 4.1.x) private static int WINDOW_FLAG_FULLSCREEN = 0x00000400; private static int WINDOW_FLAG_FORCE_NOT_FULLSCREEN = 0x00000800; private static int WINDOW_FLAG_LAYOUT_IN_SCREEN = 0x00000100; private static int WINDOW_FLAG_TRANSLUCENT_STATUS = 0x04000000; private static int WINDOW_FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS = -2147483648; // Added in API 21 (Android 5.0) // Current values private static int systemUiVisibilityValue; private static int flagsValue; #endif // Properties private static States _statusBarState; private static uint _statusBarColor = DEFAULT_BACKGROUND_COLOR; private static bool _isStatusBarTranslucent; private static bool _dimmed; // ================================================================================================================ // INTERNAL INTERFACE --------------------------------------------------------------------------------------------- static AndroidStatusBar() { ApplyUIStates(); ApplyUIColors(); } private static void ApplyUIStates() { #if UNITY_ANDROID && !UNITY_EDITOR int newFlagsValue = 0; int newSystemUiVisibilityValue = 0; // Apply dim values if (_dimmed) newSystemUiVisibilityValue |= VIEW_SYSTEM_UI_FLAG_LOW_PROFILE; // Apply color values if (_statusBarColor != DEFAULT_BACKGROUND_COLOR) newFlagsValue |= WINDOW_FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; // Apply status bar values switch (_statusBarState) { case States.Visible: _isStatusBarTranslucent = false; newFlagsValue |= WINDOW_FLAG_FORCE_NOT_FULLSCREEN; break; case States.VisibleOverContent: _isStatusBarTranslucent = false; newFlagsValue |= WINDOW_FLAG_FORCE_NOT_FULLSCREEN | WINDOW_FLAG_LAYOUT_IN_SCREEN; newSystemUiVisibilityValue |= VIEW_SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; break; case States.TranslucentOverContent: _isStatusBarTranslucent = true; newFlagsValue |= WINDOW_FLAG_FORCE_NOT_FULLSCREEN | WINDOW_FLAG_LAYOUT_IN_SCREEN | WINDOW_FLAG_TRANSLUCENT_STATUS; newSystemUiVisibilityValue |= VIEW_SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; break; case States.Hidden: newFlagsValue |= WINDOW_FLAG_FULLSCREEN | WINDOW_FLAG_LAYOUT_IN_SCREEN; if (_isStatusBarTranslucent) newFlagsValue |= WINDOW_FLAG_TRANSLUCENT_STATUS; break; } if (Screen.fullScreen) Screen.fullScreen = false; // Applies everything natively SetFlags(newFlagsValue); SetSystemUiVisibility(newSystemUiVisibilityValue); #endif } private static void ApplyUIColors() { #if UNITY_ANDROID && !UNITY_EDITOR RunOnAndroidUiThread(ApplyUIColorsAndroidInThread); #endif } #if UNITY_ANDROID private static void RunOnAndroidUiThread(Action target) { using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { using (var activity = unityPlayer.GetStatic("currentActivity")) { activity.Call("runOnUiThread", new AndroidJavaRunnable(target)); } } } private static void SetSystemUiVisibility(int value) { if (systemUiVisibilityValue != value) { systemUiVisibilityValue = value; RunOnAndroidUiThread(SetSystemUiVisibilityInThread); } } private static void SetSystemUiVisibilityInThread() { using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { using (var activity = unityPlayer.GetStatic("currentActivity")) { using (var window = activity.Call("getWindow")) { using (var view = window.Call("getDecorView")) { view.Call("setSystemUiVisibility", systemUiVisibilityValue); } } } } } private static void SetFlags(int value) { if (flagsValue != value) { flagsValue = value; RunOnAndroidUiThread(SetFlagsInThread); } } private static void SetFlagsInThread() { using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { using (var activity = unityPlayer.GetStatic("currentActivity")) { using (var window = activity.Call("getWindow")) { window.Call("setFlags", flagsValue, -1); // (int)0x7FFFFFFF } } } } private static void ApplyUIColorsAndroidInThread() { using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { using (var activity = unityPlayer.GetStatic("currentActivity")) { using (var window = activity.Call("getWindow")) { window.Call("setStatusBarColor", unchecked((int)_statusBarColor)); } } } } #endif // ================================================================================================================ // ACCESSOR INTERFACE --------------------------------------------------------------------------------------------- public static States statusBarState { get { return _statusBarState; } set { if (_statusBarState != value) { _statusBarState = value; ApplyUIStates(); } } } public static bool dimmed { get { return _dimmed; } set { if (_dimmed != value) { _dimmed = value; ApplyUIStates(); } } } public static uint statusBarColor { get { return _statusBarColor; } set { if (_statusBarColor != value) { _statusBarColor = value; ApplyUIColors(); ApplyUIStates(); } } } }