/* *[Tooltip("状态栏是否显示状态及通知")] public bool statusBar; [Tooltip("状态栏样式")] public AndroidStatusBar.States states = AndroidStatusBar.States.Visible; // Use this for initialization void Awake() { if (Application.platform == RuntimePlatform.Android) { AndroidStatusBar.dimmed = !statusBar; //当AndroidStatusBar.dimmed=false时,状态栏显示所有状态及通知图标 //当AndroidStatusBar.dimmed=true时,状态栏仅电量和时间,不显示其他状态及通知 ////显示状态栏,占用屏幕最上方的一部分像素 //AndroidStatusBar.statusBarState = AndroidStatusBar.States.Visible; ////悬浮显示状态栏,不占用屏幕像素 //AndroidStatusBar.statusBarState = AndroidStatusBar.States.VisibleOverContent; ////透明悬浮显示状态栏,不占用屏幕像素 //AndroidStatusBar.statusBarState = AndroidStatusBar.States.TranslucentOverContent; ////隐藏状态栏 //AndroidStatusBar.statusBarState = AndroidStatusBar.States.Hidden; AndroidStatusBar.statusBarState = states; } } */ using System; using System.Collections.Generic; using UnityEngine; namespace Coolape { public class AndroidStatusBar { // Enums public enum States { Unknown, Visible, VisibleOverContent, TranslucentOverContent, Hidden, } // Constants public const uint DEFAULT_BACKGROUND_COLOR = 0xff000000; public const uint DEFAULT_WHITE_COLOR = 0xffffffff; #if UNITY_ANDROID // Original Android flags private const int VIEW_SYSTEM_UI_FLAG_VISIBLE = 0; // Added in API 14 (Android 4.0.x): Status bar visible (the default) private const int VIEW_SYSTEM_UI_FLAG_LOW_PROFILE = 1; // Added in API 14 (Android 4.0.x): Low profile for games, book readers, and video players; the status bar and/or navigation icons are dimmed out (if visible) private const int VIEW_SYSTEM_UI_FLAG_HIDE_NAVIGATION = 2; // Added in API 14 (Android 4.0.x): Hides all navigation. Cleared when theres any user interaction. private const int VIEW_SYSTEM_UI_FLAG_FULLSCREEN = 4; // Added in API 16 (Android 4.1.x): Hides status bar. Does nothing in Unity (already hidden if "status bar hidden" is checked) private const int VIEW_SYSTEM_UI_FLAG_LAYOUT_STABLE = 256; // Added in API 16 (Android 4.1.x): ? private const int VIEW_SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 512; // Added in API 16 (Android 4.1.x): like HIDE_NAVIGATION, but for layouts? it causes the layout to be drawn like that, even if the whole view isn't (to avoid artifacts in animation) private const int VIEW_SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 1024; // Added in API 16 (Android 4.1.x): like FULLSCREEN, but for layouts? it causes the layout to be drawn like that, even if the whole view isn't (to avoid artifacts in animation) private const int VIEW_SYSTEM_UI_FLAG_IMMERSIVE = 2048; // Added in API 19 (Android 4.4): like HIDE_NAVIGATION, but interactive (it's a modifier for HIDE_NAVIGATION, needs to be used with it) private const int VIEW_SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 4096; // Added in API 19 (Android 4.4): tells that HIDE_NAVIGATION and FULSCREEN are interactive (also just a modifier) public static int WINDOW_FLAG_FULLSCREEN = 0x00000400; public static int WINDOW_FLAG_FORCE_NOT_FULLSCREEN = 0x00000800; public static int WINDOW_FLAG_LAYOUT_NO_LIMITS = 0x00000200; public static int WINDOW_FLAG_LAYOUT_IN_SCREEN = 0x00000100; public static int WINDOW_FLAG_TRANSLUCENT_STATUS = 0x04000000; public static int WINDOW_FLAG_TRANSLUCENT_NAVIGATION = 0x08000000; public static int WINDOW_FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS = -2147483648; // 0x80000000; // Added in API 21 (Android 5.0): tells the Window is responsible for drawing the background for the system bars. If set, the system bars are drawn with a transparent background and the corresponding areas in this window are filled with the colors specified in getStatusBarColor() and getNavigationBarColor() // 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; static AndroidStatusBar () { applyUIStates (); applyUIColors (); } private static void applyUIStates () { #if UNITY_ANDROID if (Application.platform == RuntimePlatform.Android) { 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 if (Application.platform == RuntimePlatform.Android) { 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); } } } } } public 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, flagsValue); // (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 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 void setColor(uint color) { _statusBarColor = color; applyUIColors(); } public static uint statusBarColor { get { return _statusBarColor; } set { if (_statusBarColor != value) { _statusBarColor = value; applyUIColors (); applyUIStates (); } } } } }