Forest_Client/Forest/Assets/PhxhSDK/Phxh/Others/DeviceHelper.cs

523 lines
17 KiB
C#

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.Android;
namespace PhxhSDK
{
public class Device : SingletonMono<Device>
{
// 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;
/// <summary>
/// 是否获取到所有权限
/// </summary>
private bool isGetAllPermission;
/// <summary>
/// 是否获取到wifi状态权限
/// </summary>
private bool isGetACCESS_WIFI_STATEPermission;
/// <summary>
/// 权限集合
/// </summary>
private readonly HashSet<string> 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<AndroidJavaObject>("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;
}
/// <summary>
/// 申请权限被拒绝
/// </summary>
/// <param name="permission"></param>
private void OnPermissionDenied(string permission)
{
DebugUtil.Log($"申请{permission}权限被拒绝");
}
/// <summary>
/// 申请权限被拒绝,且不再询问
/// </summary>
/// <param name="permission"></param>
private void OnPermissionDeniedAndDontAskAgain(string permission)
{
DebugUtil.Log($"申请{permission}权限被拒绝,且不再询问");
}
/// <summary>
/// 申请权限成功
/// </summary>
/// <param name="getPermission"></param>
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
{
/// <summary>
/// 网络状态
/// </summary>
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; }
/// <summary>
/// 获取电池电量
/// </summary>
/// <returns>0f-1f</returns>
public static float GetBatteryLevel()
{
return SystemInfo.batteryLevel;
}
/// <summary>
/// 获取网络信号
/// </summary>
/// <returns>0f-1f</returns>
public static float GetNetworkSignal()
{
if (Application.platform == RuntimePlatform.Android)
return GetAndroidNetworkSignal();
else if (Application.platform == RuntimePlatform.IPhonePlayer)
return GetIosNetworkSignal();
else
return 1f;
}
/// <summary>
/// 获取安卓的网络信号强度
/// </summary>
/// <returns>0f-1f</returns>
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<AndroidJavaObject>("getApplicationContext");
AndroidJavaObject wifiManager = context.Call<AndroidJavaObject>("getSystemService", "wifi");
if (wifiManager != null)
{
AndroidJavaObject wifiInfo = wifiManager.Call<AndroidJavaObject>("getConnectionInfo");
int signalStrength = wifiInfo.Call<int>("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<AndroidJavaObject>("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;
}
/// <summary>
/// 获取屏幕宽高比
/// </summary>
/// <returns></returns>
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;
}
}
}