221 lines
6.9 KiB
C#
221 lines
6.9 KiB
C#
|
|
|
||
|
|
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<AndroidJavaObject>("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<AndroidJavaObject>("currentActivity"))
|
||
|
|
{
|
||
|
|
using (var window = activity.Call<AndroidJavaObject>("getWindow"))
|
||
|
|
{
|
||
|
|
using (var view = window.Call<AndroidJavaObject>("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<AndroidJavaObject>("currentActivity"))
|
||
|
|
{
|
||
|
|
using (var window = activity.Call<AndroidJavaObject>("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<AndroidJavaObject>("currentActivity"))
|
||
|
|
{
|
||
|
|
using (var window = activity.Call<AndroidJavaObject>("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();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|