using System; using System.Collections.Generic; using System.Reflection; using System.Text.RegularExpressions; using UnityEngine; using UnityEngine.Android; namespace PhxhSDK { public class Device : SingletonMono { // android返回键功能 private Action BackButtonCallbacks { get; set; } public static readonly Vector2 UIScreenSize = new Vector2(1920, 1080); public static readonly Vector2 UIScreenSizePortrait = new Vector2(1080, 1920); private AndroidJavaObject androidActivity; private AndroidJavaObject applicationContext; /// /// 是否获取到所有权限 /// private bool isGetAllPermission; /// /// 是否获取到wifi状态权限 /// private bool isGetACCESS_WIFI_STATEPermission; /// /// 权限集合 /// private readonly HashSet setPermission = new() { Constants.AndroidPermission.ACCESS_WIFI_STATE, // 获取wifi状态 Constants.AndroidPermission.ACCESS_NETWORK_STATE, // 获取移动网络状态 }; public AndroidJavaObject AndroidActivity { get { if (androidActivity == null) { using AndroidJavaClass androidJavaClass = new("com.unity3d.player.UnityPlayer"); androidActivity = androidJavaClass.GetStatic("currentActivity"); } return androidActivity; } } public bool IsGetACCESS_WIFI_STATEPermission { get { return isGetACCESS_WIFI_STATEPermission; } } private void Awake() { if (Application.platform == RuntimePlatform.Android) { PermissionCallbacks permissionCallbacks = new(); permissionCallbacks.PermissionDenied += OnPermissionDenied; permissionCallbacks.PermissionGranted += OnPermissionGranted; permissionCallbacks.PermissionDeniedAndDontAskAgain += OnPermissionDeniedAndDontAskAgain; // 申请权限 foreach (string permission in setPermission) { Permission.RequestUserPermission(permission, permissionCallbacks); } } } // Update is called once per frame private void Update() { #if UNITY_ANDROID || UNITY_EDITOR if (Input.GetKeyDown(KeyCode.Escape) && BackButtonCallbacks != null) BackButtonCallbacks.Invoke(); #endif } public void AddBackButtonCallback(Action action) { BackButtonCallbacks += action; } public void RemoveBackButtonCallback(Action action) { BackButtonCallbacks -= action; } /// /// 申请权限被拒绝 /// /// private void OnPermissionDenied(string permission) { DebugUtil.Log($"申请{permission}权限被拒绝"); } /// /// 申请权限被拒绝,且不再询问 /// /// private void OnPermissionDeniedAndDontAskAgain(string permission) { DebugUtil.Log($"申请{permission}权限被拒绝,且不再询问"); } /// /// 申请权限成功 /// /// private void OnPermissionGranted(string getPermission) { if (Constants.AndroidPermission.ACCESS_WIFI_STATE == getPermission) isGetACCESS_WIFI_STATEPermission = true; foreach (string permission in setPermission) { if (!Permission.HasUserAuthorizedPermission(permission)) return; } //一次申请多个权限,比如申请2个。会依次弹窗进行申请,在全部交互完成后才开始回调接口。如若玩家全部同意。这里会回调2次 //所以这里需要加个变量防止重复回调 if (!isGetAllPermission) { isGetAllPermission = true; //在这里处理权限通过的逻辑 //do something Debug.Log("所有权限申请通过"); } } } public static class DeviceHelper { /// /// 网络状态 /// public enum NetworkStatus { Unknown = 0, NoNetwork = 1, Cellular = 2, Wifi = 3 } private static readonly string s_OSName = SystemInfo.operatingSystem; private static readonly string s_Resolution = Screen.currentResolution.ToString(); private static readonly string s_SystemLanguage = Application.systemLanguage.ToString(); private static readonly string s_AppVersion = Application.version; private static readonly int s_SystemMemorySize = SystemInfo.systemMemorySize; private static readonly string s_DeviceModel = SystemInfo.deviceModel; private static readonly string s_ProcessorType = SystemInfo.processorType; private static readonly string s_DeviceId = SystemInfo.deviceUniqueIdentifier; static DeviceHelper() { string versionPattern; if (Application.platform == RuntimePlatform.Android) versionPattern = "API-([\\d|\\.]*)"; else versionPattern = "[^\\d]*([\\d|\\.]*)"; var match = Regex.Match(s_OSName, versionPattern, RegexOptions.IgnoreCase); if (match.Success) { var osVersion = match.Groups[1].Value; var versionArray = osVersion.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); s_mainOSVersion = versionArray.Length > 0 ? int.Parse(versionArray[0]) : 0; s_secondaryOSVersion = versionArray.Length > 1 ? int.Parse(versionArray[1]) : 0; } } public static int s_mainOSVersion { get; private set; } public static int s_secondaryOSVersion { get; private set; } /// /// 获取电池电量 /// /// 0f-1f public static float GetBatteryLevel() { return SystemInfo.batteryLevel; } /// /// 获取网络信号 /// /// 0f-1f public static float GetNetworkSignal() { if (Application.platform == RuntimePlatform.Android) return GetAndroidNetworkSignal(); else if (Application.platform == RuntimePlatform.IPhonePlayer) return GetIosNetworkSignal(); else return 1f; } /// /// 获取安卓的网络信号强度 /// /// 0f-1f private static float GetAndroidNetworkSignal() { if (Application.internetReachability == NetworkReachability.NotReachable) // 没有网络 return 0f; if (Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork) // Wifi { if (!Device.Instance.IsGetACCESS_WIFI_STATEPermission) return 0f; try { AndroidJavaObject context = Device.Instance.AndroidActivity.Call("getApplicationContext"); AndroidJavaObject wifiManager = context.Call("getSystemService", "wifi"); if (wifiManager != null) { AndroidJavaObject wifiInfo = wifiManager.Call("getConnectionInfo"); int signalStrength = wifiInfo.Call("getRssi"); // RSSI是接收信号强度指示 if (signalStrength <= 0 && signalStrength >= -60) return 1f; if (signalStrength < -60 && signalStrength >= -80) return 0.75f; if (signalStrength < -80 && signalStrength >= -90) return 0.5f; if (signalStrength < -90 && signalStrength >= -100) return 0.25f; return 0f; } return 0f; } catch (Exception ex) { DebugUtil.LogError(ex.Message); return 0f; } } if (Application.internetReachability == NetworkReachability.ReachableViaCarrierDataNetwork) // 移动网络 return 1f; // TODO return 1f; } private static float GetIosNetworkSignal() { if (Application.internetReachability == NetworkReachability.NotReachable) // 没有网络 return 0f; if (Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork) // Wifi return 1f; // TODO if (Application.internetReachability == NetworkReachability.ReachableViaCarrierDataNetwork) // 移动网络 return 1f; // TODO return 1f; } public static string GetAppVersion() { return s_AppVersion; } public static long GetTotalMemory() { return s_SystemMemorySize; } public static string GetDeviceModel() { return s_DeviceModel; } // TODO public static string GetRegion() { return s_SystemLanguage; } // TODO public static string GetCountry() { return s_SystemLanguage; } public static string GetOSName() { return s_OSName; } public static string GetOSVersion() { return s_OSName; } public static string GetCPU() { return s_ProcessorType; } public static void CancelNotification(int id) { #if UNITY_ANDROID CallActivityFunction("CancelNotification", id.ToString()); #endif } public static void ScheduleLocalNotification(int id, string title, string message, int seconds, bool sound) { #if UNITY_ANDROID CallActivityFunction("ScheduleLocalNotification", id.ToString(), title, message, seconds.ToString()); #endif } // TODO public static string GetTimezone() { try { return TimeZoneInfo.Local.StandardName; } catch { return "UNKNOWN"; } } public static string GetPlatformString() { #if UNITY_IOS if (SystemInfo.deviceModel.Contains("iPad")) return "Ipad"; return "Iphone"; #elif UNITY_ANDROID return "Android"; #else return "UnityEditor"; #endif } private static void CallActivityFunction(string methodName, params object[] args) { #if UNITY_ANDROID if (Application.platform != RuntimePlatform.Android) { return; } try { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic("currentActivity"); jo.Call(methodName, args); //jo.Call("runOnUiThread", new AndroidJavaRunnable(() => { jo.Call(methodName, args); })); } catch (System.Exception ex) { DebugUtil.LogWarning(ex.Message); } #endif } // public static NetworkStatus GetNetworkStatus() // { // switch (APIManager.Instance.GetNetworkStatus) // { // case NetworkReachability.ReachableViaCarrierDataNetwork: // return NetworkStatus.Cellular; // case NetworkReachability.ReachableViaLocalAreaNetwork: // return NetworkStatus.Wifi; // case NetworkReachability.NotReachable: // return NetworkStatus.NoNetwork; // default: // return NetworkStatus.Unknown; // } // } // public static string GetDeviceType() // { // return DragonNativeBridge.getDeviceType(); // } public static bool IsNative() { #if UNITY_EDITOR || UNITY_IOS || UNITY_ANDROID || UNITY_FACEBOOK return true; #else return false; #endif } public static bool IsIOSOrAndroid() { #if UNITY_EDITOR || UNITY_IOS || UNITY_ANDROID return true; #else return false; #endif } public static string GetSchemeParams() { #if UNITY_IOS || UNITY_ANDROID //if(Dlugin.SDK.GetInstance().osService != null) //{ // return Dlugin.SDK.GetInstance().osService.GetUnprocessedURLRequest(); //} #endif return ""; } public static ulong CurrentTimeMillis() { var epochStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); return (ulong)(DateTime.UtcNow - epochStart).TotalMilliseconds; } public static string GetResolution() { return s_Resolution; } public static string GetLanguage() { return s_SystemLanguage; } public static string GetLocalIp() { return "0.0.0.0"; } public static bool IsFullScreenIOS() { #if UNITY_IOS && !UNITY_EDITOR var generation = UnityEngine.iOS.Device.generation; if (generation == UnityEngine.iOS.DeviceGeneration.iPhoneX || generation == UnityEngine.iOS.DeviceGeneration.iPhoneXR || generation == UnityEngine.iOS.DeviceGeneration.iPhoneXS || generation == UnityEngine.iOS.DeviceGeneration.iPhoneXSMax || generation == UnityEngine.iOS.DeviceGeneration.iPhone11 || generation == UnityEngine.iOS.DeviceGeneration.iPhone11Pro || generation == UnityEngine.iOS.DeviceGeneration.iPhone11ProMax || (generation == UnityEngine.iOS.DeviceGeneration.iPhoneUnknown && GetScreenWHRate() >= 2.0f)) { return true; } #endif return false; } public static bool IsFullScreenIOS_Portrait() { #if UNITY_IOS && !UNITY_EDITOR var generation = UnityEngine.iOS.Device.generation; if (generation == UnityEngine.iOS.DeviceGeneration.iPhoneX || generation == UnityEngine.iOS.DeviceGeneration.iPhoneXR || generation == UnityEngine.iOS.DeviceGeneration.iPhoneXS || generation == UnityEngine.iOS.DeviceGeneration.iPhoneXSMax || generation == UnityEngine.iOS.DeviceGeneration.iPhone11 || generation == UnityEngine.iOS.DeviceGeneration.iPhone11Pro || generation == UnityEngine.iOS.DeviceGeneration.iPhone11ProMax || (generation == UnityEngine.iOS.DeviceGeneration.iPhoneUnknown && GetScreenWHRate() <= 0.5f))// 竖屏iphone12 { return true; } #endif return false; } // 判断宽屏设备 public static bool IsWideScreenDevice() { return (float)Screen.width / Screen.height <= 1.5f; } /// /// 获取屏幕宽高比 /// /// public static float GetScreenWHRate() { return (float)Screen.width / Screen.height; } // public static string GetUserAgent() // { // return Application.productName + "/" + GetPlatform().ToString() + "/" + GetAppVersion(); // } public static Vector2 GetWidthOffset() { var rect = Screen.safeArea; var offsetLeft = rect.x / Screen.width * Device.UIScreenSize.x; var offsetRight = (1 - (rect.x + rect.width) / Screen.width) * Device.UIScreenSize.x; return new Vector2(offsetLeft, offsetRight); } public static Vector2 GetHeightOffset() { var rect = Screen.safeArea; var offsetBottom = rect.y / Screen.height* Device.UIScreenSizePortrait.y; var offsetTop = (1 - (rect.y + rect.height) / Screen.height) * Device.UIScreenSizePortrait.y; return new Vector2(offsetTop,offsetBottom ); } public static string GetDeviceId() { return s_DeviceId; } } }