diff --git a/Assets/Res/language/language.json b/Assets/Res/language/language.json index c1f88e5..288cebe 100644 --- a/Assets/Res/language/language.json +++ b/Assets/Res/language/language.json @@ -1006,7 +1006,7 @@ }, { "key": "100202", - "zh": "修改密码", + "zh": "请输入用户ID", "en": "Please enter User ID" }, { @@ -1017,7 +1017,7 @@ { "key": "100204", "zh": "请输入要共享的用户ID", - "en": "Enter shared user ID" + "en": "Please Enter shared user ID" }, { "key": "100205", diff --git a/Assets/Res/ui/deviceinfopage/设备分享页面.prefab b/Assets/Res/ui/deviceinfopage/设备分享页面.prefab index f12cc48..671312c 100644 --- a/Assets/Res/ui/deviceinfopage/设备分享页面.prefab +++ b/Assets/Res/ui/deviceinfopage/设备分享页面.prefab @@ -969,6 +969,7 @@ GameObject: - component: {fileID: 1519237044948379669} - component: {fileID: 4142448484629704935} - component: {fileID: 4921898416580924308} + - component: {fileID: 1825025902833908675} m_Layer: 5 m_Name: Text (Legacy) (1) m_TagString: Untagged @@ -1036,7 +1037,20 @@ MonoBehaviour: m_HorizontalOverflow: 1 m_VerticalOverflow: 0 m_LineSpacing: 1 - m_Text: Please enter User ID + m_Text: Enter shared user ID +--- !u!114 &1825025902833908675 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5444693722322422585} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 89f1d49b50a31514787b4e268b1c73bb, type: 3} + m_Name: + m_EditorClassIdentifier: + textKey: 100204 --- !u!1 &5524717387086965381 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Res/ui/selfpage/FAQ页面.prefab b/Assets/Res/ui/selfpage/FAQ页面.prefab index 326cfc6..04b94ae 100644 --- a/Assets/Res/ui/selfpage/FAQ页面.prefab +++ b/Assets/Res/ui/selfpage/FAQ页面.prefab @@ -3517,7 +3517,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 345, y: -564} + m_AnchoredPosition: {x: 345, y: -172} m_SizeDelta: {x: 690, y: 0} m_Pivot: {x: 0.5, y: 1} --- !u!222 &854871756318895437 @@ -10811,7 +10811,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 345, y: -2408} + m_AnchoredPosition: {x: 345, y: -466} m_SizeDelta: {x: 690, y: 0} m_Pivot: {x: 0.5, y: 1} --- !u!222 &6739308067368723960 @@ -11868,7 +11868,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 345, y: -1918} + m_AnchoredPosition: {x: 345, y: -368} m_SizeDelta: {x: 690, y: 0} m_Pivot: {x: 0.5, y: 1} --- !u!222 &5027863063353656364 @@ -12732,7 +12732,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 345, y: -1286} + m_AnchoredPosition: {x: 345, y: -270} m_SizeDelta: {x: 690, y: 0} m_Pivot: {x: 0.5, y: 1} --- !u!222 &4389568299256833371 diff --git a/Assets/Res/ui/selfpage/个人信息页.prefab b/Assets/Res/ui/selfpage/个人信息页.prefab index 8f8a0ee..3946f9e 100644 --- a/Assets/Res/ui/selfpage/个人信息页.prefab +++ b/Assets/Res/ui/selfpage/个人信息页.prefab @@ -3270,67 +3270,67 @@ PrefabInstance: - target: {fileID: 1507386632888176871, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 1507386632888176871, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 1507386632888176871, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 590 objectReference: {fileID: 0} - target: {fileID: 1507386632888176871, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_SizeDelta.y - value: 0 + value: 90 objectReference: {fileID: 0} - target: {fileID: 1507386632888176871, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 295 objectReference: {fileID: 0} - target: {fileID: 1507386632888176871, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -312 objectReference: {fileID: 0} - target: {fileID: 4296973555611399213, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 4296973555611399213, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 4296973555611399213, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 590 objectReference: {fileID: 0} - target: {fileID: 4296973555611399213, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_SizeDelta.y - value: 0 + value: 45 objectReference: {fileID: 0} - target: {fileID: 4296973555611399213, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 295 objectReference: {fileID: 0} - target: {fileID: 4296973555611399213, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -55 objectReference: {fileID: 0} - target: {fileID: 4685927451915885120, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_SizeDelta.y - value: 0 + value: 342 objectReference: {fileID: 0} - target: {fileID: 5819498693055166909, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} @@ -3340,7 +3340,7 @@ PrefabInstance: - target: {fileID: 5819498693055166909, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_IsActive - value: 1 + value: 0 objectReference: {fileID: 0} - target: {fileID: 6314676893636565267, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} @@ -3450,32 +3450,32 @@ PrefabInstance: - target: {fileID: 6936886167337472632, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 6936886167337472632, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 6936886167337472632, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 590 objectReference: {fileID: 0} - target: {fileID: 6936886167337472632, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_SizeDelta.y - value: 0 + value: 42 objectReference: {fileID: 0} - target: {fileID: 6936886167337472632, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 295 objectReference: {fileID: 0} - target: {fileID: 6936886167337472632, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -140 objectReference: {fileID: 0} - target: {fileID: 7452104535586638788, guid: 52c284b3dc8d7b94297736ede9ad1f7e, type: 3} diff --git a/Assets/Scripts/Bluetooth/BluetoothManager.cs b/Assets/Scripts/Bluetooth/BluetoothManager.cs index 7c68faa..d1034c6 100644 --- a/Assets/Scripts/Bluetooth/BluetoothManager.cs +++ b/Assets/Scripts/Bluetooth/BluetoothManager.cs @@ -2,6 +2,7 @@ using UnityEngine; using System; using System.Collections.Generic; using Kill.Core; +using Kill.UI; using Kill.UI.Components; namespace Kill.Bluetooth @@ -89,12 +90,23 @@ namespace Kill.Bluetooth private bool _isConnecting; private string _connectingAddress; + // 蓝牙启用提示相关 + private Coroutine _enableBtCoroutine; // 等待蓝牙启用的协程 + private bool _userDeniedBluetooth = false; // 用户已拒绝过蓝牙开启请求 + private bool _pendingStartScan = false; // 是否有待执行的扫描 + private float _pendingScanTimeout; // 待执行扫描的超时时间 + private string _pendingConnectAddress; // 初始化后待连接的设备地址 + private bool _wasBtOn = false; // 上一帧蓝牙是否开启(用于检测状态变化) + private Coroutine _stateMonitorCoroutine; // 蓝牙状态监控协程 + private void Awake() { if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); + _stateMonitorCoroutine = StartCoroutine(MonitorBluetoothState()); + OnDisconnected += OnSelfDisconnected; } else { @@ -106,9 +118,31 @@ namespace Kill.Bluetooth { if (Instance == this) { + OnDisconnected -= OnSelfDisconnected; + if (_stateMonitorCoroutine != null) + { + StopCoroutine(_stateMonitorCoroutine); + _stateMonitorCoroutine = null; + } Instance = null; } } + + /// + /// 蓝牙断开后延迟跳回主页 + /// + private void OnSelfDisconnected(string address) + { + IsConnected=false; + // 延迟一下确保主页能读到最新的 IsConnected 状态 + StartCoroutine(DelayedGoHome()); + } + + private System.Collections.IEnumerator DelayedGoHome() + { + yield return new WaitForSeconds(1f); + UIManager.Instance?.OpenMainPage(UIManager.PageName.homePage); + } void Start() { Initialize(); @@ -143,6 +177,20 @@ namespace Kill.Bluetooth return; } + // 如果已经在等待蓝牙启用,跳过(不取消旧请求,避免重复弹窗) + if (_enableBtCoroutine != null) + { + Log("已在等待用户启用蓝牙,跳过重复请求"); + return; + } + + // 用户已拒绝过蓝牙请求,不再自动弹出提示 + if (_userDeniedBluetooth) + { + Log("用户已拒绝蓝牙开启,跳过初始化"); + return; + } + Log("正在初始化蓝牙..."); // 先检查蓝牙是否开启,如果没有则尝试启用 @@ -153,6 +201,15 @@ namespace Kill.Bluetooth }); } + /// + /// 强制初始化蓝牙(清除用户拒绝标记,用于用户主动触发) + /// + public void ForceInitialize() + { + _userDeniedBluetooth = false; + Initialize(); + } + /// /// 检查并启用蓝牙 /// @@ -165,6 +222,7 @@ namespace Kill.Bluetooth if (bluetoothAdapter == null) { + _enableBtCoroutine = null; OnError?.Invoke("设备不支持蓝牙"); OnInitialized?.Invoke(false); return; @@ -174,22 +232,16 @@ namespace Kill.Bluetooth if (!isEnabled) { - Log("蓝牙未开启,尝试启用..."); - - // 尝试静默启用蓝牙 - bool enableSuccess = bluetoothAdapter.Call("enable"); - - if (enableSuccess) + Log("蓝牙未开启,使用 Intent 请求用户启用..."); + + using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) + using (AndroidJavaObject currentActivity = unityPlayer.GetStatic("currentActivity")) { - Log("正在启用蓝牙,等待..."); - // 等待蓝牙启用 - StartCoroutine(WaitForBluetoothEnabled(onBluetoothReady)); - } - else - { - // 静默启用失败,请求用户启用 - RequestUserEnableBluetooth(onBluetoothReady); + AndroidJavaObject intent = new AndroidJavaObject("android.content.Intent", "android.bluetooth.adapter.action.REQUEST_ENABLE"); + currentActivity.Call("startActivityForResult", intent, 1); } + + _enableBtCoroutine = StartCoroutine(WaitForBluetoothEnabled(onBluetoothReady)); } else { @@ -206,6 +258,65 @@ namespace Kill.Bluetooth #endif } +#if UNITY_ANDROID && !UNITY_EDITOR + /// + /// 轮询等待蓝牙启用(Intent 之后,最长10秒) + /// + private System.Collections.IEnumerator WaitForBluetoothEnabled(System.Action onBluetoothReady) + { + float maxTimeout = 10f; + float timer = 0f; + int checkCount = 0; + bool wasUnfocused = false; + + while (timer < maxTimeout) + { + checkCount++; + using (AndroidJavaClass btClass = new AndroidJavaClass("android.bluetooth.BluetoothAdapter")) + { + AndroidJavaObject adapter = btClass.CallStatic("getDefaultAdapter"); + if (adapter != null) + { + bool btOn = adapter.Call("isEnabled"); + if (checkCount <= 4 || checkCount % 10 == 0) + Log($"第{checkCount}次: isEnabled={btOn}, 已等待{timer:F1}s"); + if (btOn) + { + Log("蓝牙已成功启用"); + _enableBtCoroutine = null; + _userDeniedBluetooth = false; + onBluetoothReady?.Invoke(); + yield break; + } + } + } + + // 检测用户是否关闭了系统对话框:对话框弹出时 App 失去焦点,关闭后恢复 + if (!Application.isFocused) + { + wasUnfocused = true; + } + else if (wasUnfocused && timer > 0.5f) + { + // 焦点恢复但蓝牙仍未开启 → 用户拒绝了 / 关闭了对话框 + Log("检测到用户关闭了蓝牙请求对话框,停止等待"); + break; + } + + yield return new WaitForSeconds(0.2f); + timer += 0.2f; + } + + Log($"等待蓝牙启用结束 (共检查{checkCount}次,已等待{timer:F1}s)"); + _enableBtCoroutine = null; + _userDeniedBluetooth = true; + _pendingStartScan = false; + _pendingConnectAddress = null; + OnError?.Invoke("蓝牙未开启"); + OnInitialized?.Invoke(false); + } +#endif + #if UNITY_IOS && !UNITY_EDITOR [System.Runtime.InteropServices.DllImport("__Internal")] private static extern int GetBluetoothStateIOS(); @@ -231,23 +342,23 @@ namespace Kill.Bluetooth // 4 = PoweredOff (蓝牙关闭) else if (state == 4) { - Log("iOS 蓝牙未开启,提示用户"); - // iOS 不能自动打开蓝牙,只能提示用户去设置中开启 + Log("iOS 蓝牙未开启,跳转到系统设置..."); ShowIOSTurnOnBluetoothPrompt(); - OnError?.Invoke("请在系统设置中开启蓝牙"); - OnInitialized?.Invoke(false); + // 等待用户从设置返回(检测焦点变化 + 轮询蓝牙状态) + _enableBtCoroutine = StartCoroutine(WaitForIOSBluetoothEnabled(onBluetoothReady)); } // 3 = Unauthorized (未授权) else if (state == 3) { - Log("iOS 蓝牙未授权"); - OnError?.Invoke("请在设置中允许使用蓝牙"); - OnInitialized?.Invoke(false); + Log("iOS 蓝牙未授权,跳转到系统设置..."); + ShowIOSTurnOnBluetoothPrompt(); + _enableBtCoroutine = StartCoroutine(WaitForIOSBluetoothEnabled(onBluetoothReady)); } // 2 = Unsupported (不支持蓝牙) else if (state == 2) { Log("设备不支持蓝牙"); + _enableBtCoroutine = null; OnError?.Invoke("设备不支持蓝牙"); OnInitialized?.Invoke(false); } @@ -259,96 +370,142 @@ namespace Kill.Bluetooth } } + /// + /// iOS: 等待用户从设置返回并开启蓝牙(检测焦点 + 轮询) + /// + private System.Collections.IEnumerator WaitForIOSBluetoothEnabled(System.Action onBluetoothReady) + { + float maxTimeout = 15f; + float timer = 0f; + int checkCount = 0; + bool wasUnfocused = false; + + while (timer < maxTimeout) + { + checkCount++; + int state = GetBluetoothStateIOS(); + + if (checkCount <= 4 || checkCount % 10 == 0) + Log($"iOS 第{checkCount}次: state={state}, 已等待{timer:F1}s"); + + // 5 = PoweredOn + if (state == 5) + { + Log("iOS 蓝牙已开启"); + _enableBtCoroutine = null; + _userDeniedBluetooth = false; + onBluetoothReady?.Invoke(); + yield break; + } + + // 检测用户从设置返回 + if (!Application.isFocused) + { + wasUnfocused = true; + } + else if (wasUnfocused && timer > 1f) + { + // 从系统设置返回但蓝牙仍未开启 → 用户未操作 + Log("iOS: 从设置返回,蓝牙未开启,停止等待"); + break; + } + + yield return new WaitForSeconds(0.3f); + timer += 0.3f; + } + + Log($"iOS 等待蓝牙启用结束 (共检查{checkCount}次,已等待{timer:F1}s)"); + _enableBtCoroutine = null; + _userDeniedBluetooth = true; + _pendingStartScan = false; + _pendingConnectAddress = null; + OnError?.Invoke("请在系统设置中开启蓝牙"); + OnInitialized?.Invoke(false); + } + /// /// 显示 iOS 开启蓝牙提示 /// private void ShowIOSTurnOnBluetoothPrompt() { - // 可以在这里显示一个弹窗,引导用户去设置 - // 或者使用原生插件跳转到设置页面 OpenBluetoothSettingsIOS(); } #endif + /// + /// 监控蓝牙开关状态变化(App运行时) + /// + private System.Collections.IEnumerator MonitorBluetoothState() + { + yield return new WaitForSeconds(2f); // 初始延迟 + + while (true) + { + yield return new WaitForSeconds(2f); + + bool btOn = CheckIfBluetoothIsOn(); + + if (!_wasBtOn && btOn) + { + if (!IsInitialized && !_userDeniedBluetooth) + { + Log("检测到蓝牙已开启,自动初始化..."); + Initialize(); + } + } + else if (_wasBtOn && !btOn) + { + Log("检测到蓝牙已关闭,清理状态..."); + if (_enableBtCoroutine != null) + { + StopCoroutine(_enableBtCoroutine); + _enableBtCoroutine = null; + } + if (IsConnected) + { + Disconnect(); + } + if (IsScanning) + { + StopScan(); + } + IsInitialized = false; + _isFullyInitialized = false; + _pendingStartScan = false; + _pendingConnectAddress = null; + OnInitialized?.Invoke(false); + } + + _wasBtOn = btOn; + } + } + + /// + /// 跨平台检查蓝牙是否开启 + /// + private bool CheckIfBluetoothIsOn() + { #if UNITY_ANDROID && !UNITY_EDITOR - /// - /// 等待蓝牙启用 - /// - private System.Collections.IEnumerator WaitForBluetoothEnabled(System.Action onBluetoothReady) - { - float timeout = 5f; - float timer = 0f; - - while (timer < timeout) + try { - using (AndroidJavaClass bluetoothAdapterClass = new AndroidJavaClass("android.bluetooth.BluetoothAdapter")) + using (AndroidJavaClass btClass = new AndroidJavaClass("android.bluetooth.BluetoothAdapter")) { - AndroidJavaObject bluetoothAdapter = bluetoothAdapterClass.CallStatic("getDefaultAdapter"); - if (bluetoothAdapter != null && bluetoothAdapter.Call("isEnabled")) - { - Log("蓝牙已成功启用"); - onBluetoothReady?.Invoke(); - yield break; - } + AndroidJavaObject adapter = btClass.CallStatic("getDefaultAdapter"); + if (adapter != null) + return adapter.Call("isEnabled"); } - - yield return new WaitForSeconds(0.5f); - timer += 0.5f; } - - Log("等待蓝牙启用超时"); - OnError?.Invoke("蓝牙启用超时"); - OnInitialized?.Invoke(false); - } - - /// - /// 请求用户启用蓝牙 - /// - private void RequestUserEnableBluetooth(System.Action onBluetoothReady) - { - Log("请求用户启用蓝牙..."); - - using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) - using (AndroidJavaObject currentActivity = unityPlayer.GetStatic("currentActivity")) + catch (System.Exception ex) { - AndroidJavaObject intent = new AndroidJavaObject("android.content.Intent", "android.bluetooth.adapter.action.REQUEST_ENABLE"); - currentActivity.Call("startActivityForResult", intent, 1); + Log($"检查蓝牙状态异常: {ex.Message}"); } - - // 等待用户响应 - StartCoroutine(WaitForUserEnableBluetooth(onBluetoothReady)); - } - - /// - /// 等待用户启用蓝牙 - /// - private System.Collections.IEnumerator WaitForUserEnableBluetooth(System.Action onBluetoothReady) - { - float timeout = 30f; - float timer = 0f; - - while (timer < timeout) - { - using (AndroidJavaClass bluetoothAdapterClass = new AndroidJavaClass("android.bluetooth.BluetoothAdapter")) - { - AndroidJavaObject bluetoothAdapter = bluetoothAdapterClass.CallStatic("getDefaultAdapter"); - if (bluetoothAdapter != null && bluetoothAdapter.Call("isEnabled")) - { - Log("用户已启用蓝牙"); - onBluetoothReady?.Invoke(); - yield break; - } - } - - yield return new WaitForSeconds(0.5f); - timer += 0.5f; - } - - Log("用户未启用蓝牙或超时"); - OnError?.Invoke("请启用蓝牙后重试"); - OnInitialized?.Invoke(false); - } + return false; +#elif UNITY_IOS && !UNITY_EDITOR + return GetBluetoothStateIOS() == 5; +#else + return true; #endif + } /// /// 执行蓝牙初始化 @@ -365,8 +522,27 @@ namespace Kill.Bluetooth { IsInitialized = true; _isFullyInitialized = true; + _enableBtCoroutine = null; + _userDeniedBluetooth = false; Log("蓝牙初始化成功"); OnInitialized?.Invoke(true); + + // 如果有待执行的扫描任务,立即执行 + if (_pendingStartScan) + { + _pendingStartScan = false; + Log($"执行待处理的扫描,超时: {_pendingScanTimeout}秒"); + DoStartScan(_pendingScanTimeout); + } + + // 如果有待连接的设备地址,连接 + if (!string.IsNullOrEmpty(_pendingConnectAddress)) + { + var addr = _pendingConnectAddress; + _pendingConnectAddress = null; + Log($"执行待处理的连接: {addr}"); + StartCoroutine(DelayedConnectAfterInit(addr)); + } }, (error) => { @@ -377,7 +553,26 @@ namespace Kill.Bluetooth Log("继续初始化..."); IsInitialized = true; _isFullyInitialized = true; + _enableBtCoroutine = null; + _userDeniedBluetooth = false; OnInitialized?.Invoke(true); + + // 如果有待执行的扫描任务,立即执行 + if (_pendingStartScan) + { + _pendingStartScan = false; + Log($"执行待处理的扫描,超时: {_pendingScanTimeout}秒"); + DoStartScan(_pendingScanTimeout); + } + + // 如果有待连接的设备地址,连接 + if (!string.IsNullOrEmpty(_pendingConnectAddress)) + { + var addr = _pendingConnectAddress; + _pendingConnectAddress = null; + Log($"执行待处理的连接: {addr}"); + StartCoroutine(DelayedConnectAfterInit(addr)); + } } // 如果已经初始化完成,这是运行时错误,不是初始化错误 else if (_isFullyInitialized) @@ -388,6 +583,7 @@ namespace Kill.Bluetooth else { Log($"蓝牙初始化失败: {error}"); + _enableBtCoroutine = null; OnError?.Invoke($"初始化失败: {error}"); OnInitialized?.Invoke(false); } @@ -448,6 +644,15 @@ namespace Kill.Bluetooth } } + /// + /// 初始化完成后延迟连接设备 + /// + private System.Collections.IEnumerator DelayedConnectAfterInit(string address) + { + yield return new WaitForSeconds(0.5f); + Connect(address); + } + @@ -460,10 +665,21 @@ namespace Kill.Bluetooth { if (!IsInitialized) { - OnError?.Invoke("蓝牙未初始化,请先调用Initialize()"); + Log("蓝牙未初始化,自动触发初始化流程..."); + _pendingStartScan = true; + _pendingScanTimeout = timeout; + Initialize(); return; } + DoStartScan(timeout); + } + + /// + /// 实际执行扫描逻辑 + /// + private void DoStartScan(float timeout) + { if (IsScanning) { Log("已经在扫描中,先停止当前扫描..."); @@ -546,7 +762,11 @@ namespace Kill.Bluetooth { if (!IsInitialized) { - OnError?.Invoke("蓝牙未初始化"); + Log("蓝牙未初始化,自动触发初始化流程..."); + _pendingStartScan = true; + _pendingScanTimeout = 999f; + _pendingConnectAddress = deviceAddress; + Initialize(); return; } diff --git a/Assets/Scripts/Network/ResponseCode.cs b/Assets/Scripts/Network/ResponseCode.cs index 1ab2ed1..2d720c7 100644 --- a/Assets/Scripts/Network/ResponseCode.cs +++ b/Assets/Scripts/Network/ResponseCode.cs @@ -156,8 +156,7 @@ namespace Kill.Network } else { - // 自动显示错误提示 - ShowErrorTip(code.ToString()); + ToastUI.ShowText(message); } } diff --git a/Assets/Scripts/UI/Pages/ConnectDevice/ConnectDevicePageCtrl.cs b/Assets/Scripts/UI/Pages/ConnectDevice/ConnectDevicePageCtrl.cs index 6e03e2e..6cd6e8e 100644 --- a/Assets/Scripts/UI/Pages/ConnectDevice/ConnectDevicePageCtrl.cs +++ b/Assets/Scripts/UI/Pages/ConnectDevice/ConnectDevicePageCtrl.cs @@ -150,7 +150,7 @@ public class ConnectDevicePageCtrl : MonoBehaviour if (string.IsNullOrEmpty(ssid)) { - ToastUI.ShowText(LanguageManager.Instance.GetLanguage("100082") ?? "请输入WiFi名称"); + ToastUI.Show("100082"); return; } @@ -177,7 +177,7 @@ public class ConnectDevicePageCtrl : MonoBehaviour } else { - ToastUI.ShowText(LanguageManager.Instance.GetLanguage("100083") ?? "WiFi配置失败"); + ToastUI.Show("100083");; } }); }); @@ -353,6 +353,8 @@ public class ConnectDevicePageCtrl : MonoBehaviour deviceObjects.Clear(); } deviceObjects = new List(); + // 用户进入配网页面,强制初始化以触发蓝牙开启提示 + BluetoothManager.Instance.ForceInitialize(); BluetoothManager.Instance.StartScan(999f); // 扫描999秒 } } diff --git a/Assets/Scripts/UI/Pages/HomePage/HomePageChartsCtrl.cs b/Assets/Scripts/UI/Pages/HomePage/HomePageChartsCtrl.cs index 1398d33..edceedb 100644 --- a/Assets/Scripts/UI/Pages/HomePage/HomePageChartsCtrl.cs +++ b/Assets/Scripts/UI/Pages/HomePage/HomePageChartsCtrl.cs @@ -127,18 +127,18 @@ namespace Kill.UI.Pages switch (nowChartIndex) { case 0: - startTime = now.AddDays(-1).ToString("yyyy-MM-dd"); + startTime = now.AddDays(-1).ToString("yyyy-MM-dd 00:00:00"); break; case 1: - startTime = now.AddDays(-((int)now.DayOfWeek + 1)).ToString("yyyy-MM-dd"); + startTime = now.AddDays(-((int)now.DayOfWeek + 1)).ToString("yyyy-MM-dd 00:00:00"); break; case 2: - startTime = new DateTime(now.Year, now.Month, 1).ToString("yyyy-MM-dd"); + startTime = new DateTime(now.Year, now.Month, 1).ToString("yyyy-MM-dd 00:00:00"); break; case 3: - startTime = new DateTime(now.Year, 1, 1).ToString("yyyy-MM-dd"); + startTime = new DateTime(now.Year, 1, 1).ToString("yyyy-MM-dd 00:00:00"); break; } diff --git a/Assets/Scripts/UI/Pages/HomePage/HomePageCtrl.cs b/Assets/Scripts/UI/Pages/HomePage/HomePageCtrl.cs index b2b1c1f..7f7200d 100644 --- a/Assets/Scripts/UI/Pages/HomePage/HomePageCtrl.cs +++ b/Assets/Scripts/UI/Pages/HomePage/HomePageCtrl.cs @@ -328,7 +328,7 @@ namespace Kill.UI.Pages isQueryingStatus = false; statusQueryQueue?.Clear(); UIManager.Instance?.ClearBackAction(); - UIManager.Instance.OpenPage(UIManager.PageName.homePage, null, true); + // OpenPage 已移至 BluetoothManager.OnSelfDisconnected(全局监听 + 延迟) if(bluetoothDeviceInfoCoroutine!=null) { StopCoroutine(bluetoothDeviceInfoCoroutine); diff --git a/Assets/Scripts/UI/Pages/HomePage/HomePageDeviceState.cs b/Assets/Scripts/UI/Pages/HomePage/HomePageDeviceState.cs index 4aa6869..9e509d2 100644 --- a/Assets/Scripts/UI/Pages/HomePage/HomePageDeviceState.cs +++ b/Assets/Scripts/UI/Pages/HomePage/HomePageDeviceState.cs @@ -26,7 +26,6 @@ namespace Kill.UI.Pages { this.isBluetooth = isBluetooth; bluetoothStateIcon.color = stateBgColor[isBluetooth ? 1 : 0]; - bluetoothSearchIcon.SetActive(!isBluetooth); wifiStateIcon.color = stateBgColor[isWifi ? 1 : 0]; bool isOnline = isBluetooth || isWifi; onlineStateIcon.sprite = onlineState[isOnline ? 1 : 0]; @@ -44,9 +43,16 @@ namespace Kill.UI.Pages } public void ClickScan() { - if(!BluetoothManager.Instance.IsConnected) + if (!BluetoothManager.Instance.IsConnected) + { + // 用户主动点击,强制初始化以触发蓝牙开启提示 + BluetoothManager.Instance.ForceInitialize(); BluetoothManager.Instance.StartScan(10); - bluetoothSearchIcon.SetActive(true); + } + else + { + return; + } } } }