killapp/Assets/Scripts/Bluetooth/BluetoothManager.cs

981 lines
34 KiB
C#
Raw Normal View History

2026-04-16 14:57:19 +08:00
using UnityEngine;
using System;
using System.Collections.Generic;
using Kill.Core;
namespace Kill.Bluetooth
{
/// <summary>
/// 蓝牙设备信息
/// </summary>
[Serializable]
public class BluetoothDevice
{
public string Address; // 设备地址
public string Name; // 设备名称
public int Rssi; // 信号强度
public BluetoothDevice(string address, string name, int rssi = 0)
{
Address = address;
Name = name;
Rssi = rssi;
}
}
/// <summary>
/// 蓝牙管理器 - 提供基础的蓝牙扫描、连接、断开功能
/// </summary>
public class BluetoothManager : MonoBehaviour
{
public static BluetoothManager Instance { get; private set; }
// 事件定义
public event Action<bool> OnInitialized; // 初始化完成事件
public event Action<BluetoothDevice> OnDeviceFound; // 发现设备事件
public event Action<string> OnConnected; // 连接成功事件 (参数: 设备地址)
public event Action<string> OnConnectFailed; // 连接失败事件 (参数: 设备地址)
public event Action<string> OnDisconnected; // 断开连接事件 (参数: 设备地址)
public event Action<string> OnError; // 错误事件
public event Action<string> OnLog; // 日志事件
public event Action OnConnectedSuccess; // 连接成功并可通信事件 (无参数用于通知BLECommunicationManager)
// 状态
public bool IsInitialized { get; private set; }
public bool IsScanning { get; private set; }
public bool IsConnected { get; private set; }
public string ConnectedDeviceAddress { get; private set; }
2026-04-28 16:35:51 +08:00
private string aimMac = "";
2026-04-16 14:57:19 +08:00
// 扫描到的设备列表
public List<BluetoothDevice> DiscoveredDevices { get; private set; } = new List<BluetoothDevice>();
// 是否自动连接
public bool AutoConnect = true;
// 连接超时设置
public float ConnectionTimeout = 10f; // 连接超时时间(秒)
private float _connectionTimer;
private bool _isConnecting;
private string _connectingAddress;
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
private void OnDestroy()
{
if (Instance == this)
{
Instance = null;
}
}
2026-04-28 16:35:51 +08:00
void Start()
{
Initialize();
}
2026-04-16 14:57:19 +08:00
private void Update()
{
// 检查连接超时
if (_isConnecting)
{
_connectionTimer -= Time.deltaTime;
if (_connectionTimer <= 0)
{
// 连接超时
_isConnecting = false;
Log($"连接超时: {_connectingAddress}");
OnConnectFailed?.Invoke(_connectingAddress);
OnError?.Invoke($"连接超时: 无法连接到设备 {_connectingAddress}");
_connectingAddress = null;
}
}
}
/// <summary>
2026-04-28 16:35:51 +08:00
/// 初始化蓝牙(带自动启用)
2026-04-16 14:57:19 +08:00
/// </summary>
public void Initialize()
{
if (IsInitialized)
{
Log("蓝牙已经初始化");
OnInitialized?.Invoke(true);
return;
}
Log("正在初始化蓝牙...");
2026-04-28 16:35:51 +08:00
// 先检查蓝牙是否开启,如果没有则尝试启用
CheckAndEnableBluetooth(() =>
{
// 蓝牙已启用,执行初始化
DoInitialize();
});
}
/// <summary>
/// 检查并启用蓝牙
/// </summary>
private void CheckAndEnableBluetooth(System.Action onBluetoothReady)
{
#if UNITY_ANDROID && !UNITY_EDITOR
using (AndroidJavaClass bluetoothAdapterClass = new AndroidJavaClass("android.bluetooth.BluetoothAdapter"))
{
AndroidJavaObject bluetoothAdapter = bluetoothAdapterClass.CallStatic<AndroidJavaObject>("getDefaultAdapter");
if (bluetoothAdapter == null)
2026-04-16 14:57:19 +08:00
{
2026-04-28 16:35:51 +08:00
OnError?.Invoke("设备不支持蓝牙");
OnInitialized?.Invoke(false);
return;
}
2026-04-16 14:57:19 +08:00
2026-04-28 16:35:51 +08:00
bool isEnabled = bluetoothAdapter.Call<bool>("isEnabled");
if (!isEnabled)
2026-04-16 14:57:19 +08:00
{
2026-04-28 16:35:51 +08:00
Log("蓝牙未开启,尝试启用...");
// 尝试静默启用蓝牙
bool enableSuccess = bluetoothAdapter.Call<bool>("enable");
if (enableSuccess)
2026-04-16 14:57:19 +08:00
{
2026-04-28 16:35:51 +08:00
Log("正在启用蓝牙,等待...");
// 等待蓝牙启用
StartCoroutine(WaitForBluetoothEnabled(onBluetoothReady));
2026-04-16 14:57:19 +08:00
}
else
{
2026-04-28 16:35:51 +08:00
// 静默启用失败,请求用户启用
RequestUserEnableBluetooth(onBluetoothReady);
2026-04-16 14:57:19 +08:00
}
}
2026-04-28 16:35:51 +08:00
else
{
Log("蓝牙已开启");
onBluetoothReady?.Invoke();
}
}
#elif UNITY_IOS && !UNITY_EDITOR
// iOS 检查蓝牙状态
CheckBluetoothStateIOS(onBluetoothReady);
#else
// 其他平台直接执行初始化
onBluetoothReady?.Invoke();
#endif
2026-04-16 14:57:19 +08:00
}
2026-04-28 16:35:51 +08:00
#if UNITY_IOS && !UNITY_EDITOR
[System.Runtime.InteropServices.DllImport("__Internal")]
private static extern int GetBluetoothStateIOS();
[System.Runtime.InteropServices.DllImport("__Internal")]
private static extern void OpenBluetoothSettingsIOS();
2026-04-16 14:57:19 +08:00
/// <summary>
2026-04-28 16:35:51 +08:00
/// iOS 检查蓝牙状态
/// 0 = Unknown, 1 = Resetting, 2 = Unsupported, 3 = Unauthorized, 4 = PoweredOff, 5 = PoweredOn
2026-04-16 14:57:19 +08:00
/// </summary>
2026-04-28 16:35:51 +08:00
private void CheckBluetoothStateIOS(System.Action onBluetoothReady)
2026-04-16 14:57:19 +08:00
{
2026-04-28 16:35:51 +08:00
int state = GetBluetoothStateIOS();
Log($"iOS 蓝牙状态: {state}");
// 5 = PoweredOn (蓝牙已开启)
if (state == 5)
2026-04-16 14:57:19 +08:00
{
2026-04-28 16:35:51 +08:00
Log("iOS 蓝牙已开启");
onBluetoothReady?.Invoke();
}
// 4 = PoweredOff (蓝牙关闭)
else if (state == 4)
{
Log("iOS 蓝牙未开启,提示用户");
// iOS 不能自动打开蓝牙,只能提示用户去设置中开启
ShowIOSTurnOnBluetoothPrompt();
OnError?.Invoke("请在系统设置中开启蓝牙");
OnInitialized?.Invoke(false);
}
// 3 = Unauthorized (未授权)
else if (state == 3)
{
LogError("iOS 蓝牙未授权");
OnError?.Invoke("请在设置中允许使用蓝牙");
OnInitialized?.Invoke(false);
}
// 2 = Unsupported (不支持蓝牙)
else if (state == 2)
{
LogError("设备不支持蓝牙");
OnError?.Invoke("设备不支持蓝牙");
OnInitialized?.Invoke(false);
2026-04-16 14:57:19 +08:00
}
2026-04-28 16:35:51 +08:00
// 其他状态
else
{
Log($"iOS 蓝牙状态未知: {state},尝试继续初始化");
onBluetoothReady?.Invoke();
}
}
2026-04-16 14:57:19 +08:00
2026-04-28 16:35:51 +08:00
/// <summary>
/// 显示 iOS 开启蓝牙提示
/// </summary>
private void ShowIOSTurnOnBluetoothPrompt()
{
// 可以在这里显示一个弹窗,引导用户去设置
// 或者使用原生插件跳转到设置页面
OpenBluetoothSettingsIOS();
2026-04-16 14:57:19 +08:00
}
2026-04-28 16:35:51 +08:00
#endif
2026-04-16 14:57:19 +08:00
2026-04-28 16:35:51 +08:00
#if UNITY_ANDROID && !UNITY_EDITOR
2026-04-16 14:57:19 +08:00
/// <summary>
2026-04-28 16:35:51 +08:00
/// 等待蓝牙启用
2026-04-16 14:57:19 +08:00
/// </summary>
2026-04-28 16:35:51 +08:00
private System.Collections.IEnumerator WaitForBluetoothEnabled(System.Action onBluetoothReady)
2026-04-16 14:57:19 +08:00
{
2026-04-28 16:35:51 +08:00
float timeout = 5f;
float timer = 0f;
while (timer < timeout)
{
using (AndroidJavaClass bluetoothAdapterClass = new AndroidJavaClass("android.bluetooth.BluetoothAdapter"))
{
AndroidJavaObject bluetoothAdapter = bluetoothAdapterClass.CallStatic<AndroidJavaObject>("getDefaultAdapter");
if (bluetoothAdapter != null && bluetoothAdapter.Call<bool>("isEnabled"))
{
Log("蓝牙已成功启用");
onBluetoothReady?.Invoke();
yield break;
}
}
yield return new WaitForSeconds(0.5f);
timer += 0.5f;
}
Log("等待蓝牙启用超时");
OnError?.Invoke("蓝牙启用超时");
OnInitialized?.Invoke(false);
}
2026-04-16 14:57:19 +08:00
2026-04-28 16:35:51 +08:00
/// <summary>
/// 请求用户启用蓝牙
/// </summary>
private void RequestUserEnableBluetooth(System.Action onBluetoothReady)
{
Log("请求用户启用蓝牙...");
using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
using (AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
2026-04-16 14:57:19 +08:00
{
2026-04-28 16:35:51 +08:00
AndroidJavaObject intent = new AndroidJavaObject("android.content.Intent", "android.bluetooth.adapter.action.REQUEST_ENABLE");
currentActivity.Call("startActivityForResult", intent, 1);
2026-04-16 14:57:19 +08:00
}
2026-04-28 16:35:51 +08:00
// 等待用户响应
StartCoroutine(WaitForUserEnableBluetooth(onBluetoothReady));
}
2026-04-16 14:57:19 +08:00
2026-04-28 16:35:51 +08:00
/// <summary>
/// 等待用户启用蓝牙
/// </summary>
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<AndroidJavaObject>("getDefaultAdapter");
if (bluetoothAdapter != null && bluetoothAdapter.Call<bool>("isEnabled"))
{
Log("用户已启用蓝牙");
onBluetoothReady?.Invoke();
yield break;
}
}
yield return new WaitForSeconds(0.5f);
timer += 0.5f;
}
Log("用户未启用蓝牙或超时");
OnError?.Invoke("请启用蓝牙后重试");
OnInitialized?.Invoke(false);
}
#endif
/// <summary>
/// 执行蓝牙初始化
/// </summary>
// 标记是否已完成初始化
private bool _isFullyInitialized = false;
2026-04-16 14:57:19 +08:00
2026-04-28 16:35:51 +08:00
private void DoInitialize()
{
_isFullyInitialized = false;
BluetoothLEHardwareInterface.Initialize(true, false,
() =>
{
IsInitialized = true;
_isFullyInitialized = true;
Log("蓝牙初始化成功");
OnInitialized?.Invoke(true);
},
(error) =>
{
// 忽略 "Service not found" 错误,这是插件内部问题,不影响功能
if (error.Contains("Service not found"))
{
Log($"蓝牙初始化警告: {error}");
Log("继续初始化...");
IsInitialized = true;
_isFullyInitialized = true;
OnInitialized?.Invoke(true);
}
// 如果已经初始化完成,这是运行时错误,不是初始化错误
else if (_isFullyInitialized)
{
Log($"蓝牙运行时错误: {error}");
OnError?.Invoke(error);
}
else
{
Log($"蓝牙初始化失败: {error}");
OnError?.Invoke($"初始化失败: {error}");
OnInitialized?.Invoke(false);
}
},
needLocation: true
);
2026-04-16 14:57:19 +08:00
}
2026-04-28 16:35:51 +08:00
// /// <summary>
// /// 延迟尝试自动连接(用于初始化后)
// /// </summary>
// private void TryAutoConnectDelayed()
// {
// // 如果用户已经开始扫描或连接,跳过自动连接
// if (IsScanning || IsConnected || _isConnecting)
// {
// Log("用户正在进行扫描或连接,跳过自动连接");
// return;
// }
// TryAutoConnect();
// }
// /// <summary>
// /// 尝试自动连接上一次连接的设备
// /// </summary>
// private void TryAutoConnect()
// {
// string lastAddress = PlayerPrefs.GetString(LAST_DEVICE_ADDRESS_KEY, "");
// string lastName = PlayerPrefs.GetString(LAST_DEVICE_NAME_KEY, "");
// if (string.IsNullOrEmpty(lastAddress))
// {
// Log("没有上一次连接的设备记录");
// return;
// }
// Log($"尝试自动连接上一次设备: {lastName} [{lastAddress}]");
// // 先扫描设备,找到后再连接
// StartScanForAutoConnect(lastAddress);
// }
2026-04-16 14:57:19 +08:00
/// <summary>
/// 为自动连接扫描设备
/// </summary>
private void StartScanForAutoConnect(string targetAddress)
{
if (!IsInitialized)
{
Log("蓝牙未初始化,无法扫描");
return;
}
Log("[BLE-DEBUG] 自动连接: 开始扫描...");
// 清空设备列表
DiscoveredDevices.Clear();
// 扫描5秒
BluetoothLEHardwareInterface.ScanForPeripheralsWithServices(null,
(address, name) =>
{
// 先添加到设备列表
AddOrUpdateDevice(address, name, 0);
// 检查是否是要找的设备(统一使用大写比较)
if (address.ToUpper() == targetAddress.ToUpper())
{
Log($"[BLE-DEBUG] 自动连接: 找到设备 {name}");
BluetoothLEHardwareInterface.StopScan();
// 延迟100ms再连接确保扫描完全停止与手动连接流程一致
_pendingAutoConnectAddress = targetAddress;
Invoke(nameof(DelayedAutoConnect), 0.1f);
}
},
(address, name, rssi, bytes) =>
{
// 先添加到设备列表
AddOrUpdateDevice(address, name, rssi);
// 检查是否是要找的设备(统一使用大写比较)
if (address.ToUpper() == targetAddress.ToUpper())
{
Log($"[BLE-DEBUG] 自动连接: 找到设备 {name}, RSSI: {rssi}");
BluetoothLEHardwareInterface.StopScan();
// 延迟100ms再连接确保扫描完全停止与手动连接流程一致
_pendingAutoConnectAddress = targetAddress;
Invoke(nameof(DelayedAutoConnect), 0.1f);
}
},
true
);
// 5秒后停止扫描
Invoke(nameof(StopScan), 5f);
}
// 用于自动连接的临时地址存储
private string _pendingAutoConnectAddress;
/// <summary>
/// 延迟自动连接(确保扫描完全停止后再连接)
/// </summary>
private void DelayedAutoConnect()
{
if (!string.IsNullOrEmpty(_pendingAutoConnectAddress))
{
Log($"[BLE-DEBUG] 自动连接: 延迟连接 {_pendingAutoConnectAddress}");
Connect(_pendingAutoConnectAddress);
_pendingAutoConnectAddress = null;
}
}
2026-04-28 16:35:51 +08:00
2026-04-16 14:57:19 +08:00
2026-04-28 16:35:51 +08:00
2026-04-16 14:57:19 +08:00
/// <summary>
/// 开始扫描蓝牙设备
/// </summary>
/// <param name="timeout">扫描超时时间默认10秒</param>
public void StartScan(float timeout = 999f)
2026-04-16 14:57:19 +08:00
{
if (!IsInitialized)
{
OnError?.Invoke("蓝牙未初始化请先调用Initialize()");
return;
}
if (IsScanning)
{
Log("已经在扫描中,先停止当前扫描...");
StopScan();
}
// 如果还在连接状态,先断开
if (IsConnected)
{
Log("警告: 扫描时仍处于连接状态,先断开连接...");
Disconnect();
// 延迟一点再开始扫描
Invoke(nameof(DelayedStartScan), 1f);
return;
}
// 清空之前的设备列表
DiscoveredDevices.Clear();
IsScanning = true;
Log($"开始扫描蓝牙设备 (超时: {timeout}秒)...");
// 开始扫描
BluetoothLEHardwareInterface.ScanForPeripheralsWithServices(null,
// 回调1基础设备信息地址和名称
(address, name) =>
{
AddOrUpdateDevice(address, name, 0);
},
// 回调2包含RSSI和制造商数据
(address, name, rssi, bytes) =>
{
AddOrUpdateDevice(address, name, rssi);
},
true // 允许不带有制造商数据的RSSI
);
// 设置超时自动停止
Invoke(nameof(StopScan), timeout);
}
/// <summary>
/// 延迟开始扫描(用于断开连接后)
/// </summary>
private void DelayedStartScan()
{
Log("延迟扫描开始...");
// 清空设备列表
DiscoveredDevices.Clear();
IsScanning = true;
BluetoothLEHardwareInterface.ScanForPeripheralsWithServices(null,
(address, name) =>
{
AddOrUpdateDevice(address, name, 0);
},
(address, name, rssi, bytes) =>
{
AddOrUpdateDevice(address, name, rssi);
},
true
);
Invoke(nameof(StopScan), 10f);
}
/// <summary>
/// 停止扫描
/// </summary>
public void StopScan()
{
if (!IsScanning) return;
IsScanning = false;
// 取消所有扫描相关的Invoke
CancelInvoke(nameof(StopScan));
CancelInvoke(nameof(DelayedStartScan));
BluetoothLEHardwareInterface.StopScan();
Log("停止扫描蓝牙设备");
}
/// <summary>
/// 连接指定设备
/// </summary>
/// <param name="deviceAddress">设备地址</param>
public void Connect(string deviceAddress)
{
if (!IsInitialized)
{
OnError?.Invoke("蓝牙未初始化");
return;
}
if (IsConnected)
{
OnError?.Invoke("已连接到设备,请先断开连接");
return;
}
// 如果正在连接其他设备,先取消
if (_isConnecting)
{
Log($"取消之前的连接尝试: {_connectingAddress}");
_isConnecting = false;
}
Log($"正在连接设备: {deviceAddress}");
// 启动连接超时计时
_isConnecting = true;
// 统一使用大写格式保存地址
_connectingAddress = deviceAddress.ToUpper();
_connectionTimer = ConnectionTimeout;
BluetoothLEHardwareInterface.ConnectToPeripheral(deviceAddress,
// 连接成功回调
(address) =>
{
Log($"设备连接成功: {address}");
},
// 服务发现回调
(address, serviceUUID) =>
{
Log($"[BLE-DEBUG] 发现服务: {serviceUUID}");
},
// 特征发现回调
(address, serviceUUID, characteristicUUID) =>
{
Log($"[BLE-DEBUG] 发现特征: Service={serviceUUID}, Char={characteristicUUID}");
// 首次发现特征时设置连接状态
if (!IsConnected)
{
// 连接成功,停止超时计时
_isConnecting = false;
_connectingAddress = null;
IsConnected = true;
// 统一使用大写格式保存地址,确保与断开时使用的格式一致
ConnectedDeviceAddress = address.ToUpper();
// 保存连接的设备信息
var device = DiscoveredDevices.Find(d => d.Address.ToUpper() == address.ToUpper());
string deviceName = device != null ? device.Name : "Unknown";
2026-04-28 16:35:51 +08:00
//SaveLastConnectedDevice(address, deviceName);
2026-04-16 14:57:19 +08:00
OnConnected?.Invoke(address);
// 延迟通知连接成功并可通信
Invoke(nameof(NotifyConnectedSuccess), 0.5f);
}
},
// 断开连接回调
(disconnectAddress) =>
{
// 如果正在连接中就被断开,说明连接失败
if (_isConnecting && disconnectAddress.ToUpper() == _connectingAddress?.ToUpper())
{
_isConnecting = false;
Log($"连接失败: {disconnectAddress}");
OnConnectFailed?.Invoke(disconnectAddress);
_connectingAddress = null;
}
// 设备断开连接(使用不区分大小写的地址比较)
else if (IsConnected && disconnectAddress.ToUpper() == ConnectedDeviceAddress?.ToUpper())
{
IsConnected = false;
string disconnectedAddr = ConnectedDeviceAddress;
ConnectedDeviceAddress = null;
Log($"设备断开连接: {disconnectAddress}");
OnDisconnected?.Invoke(disconnectAddress);
// 执行清理
CleanupAfterDisconnect();
}
else
{
Log($"收到未处理的断开回调: {disconnectAddress}, 当前连接状态: IsConnected={IsConnected}");
}
}
);
}
/// <summary>
/// 按名称连接设备
/// </summary>
/// <param name="deviceName">设备名称</param>
public void ConnectByName(string deviceName)
{
var device = DiscoveredDevices.Find(d => d.Name == deviceName);
if (device != null)
{
Connect(device.Address);
}
else
{
OnError?.Invoke($"未找到设备: {deviceName}");
}
}
/// <summary>
/// 断开当前连接(带协议通知)
/// 先发送0x70断开命令给设备再断开BLE连接
/// </summary>
public void Disconnect()
{
if (!IsConnected)
{
Log("当前没有连接的设备");
return;
}
string addressToDisconnect = ConnectedDeviceAddress;
Log($"正在断开连接: {addressToDisconnect}");
// 先停止扫描,避免扫描干扰断开过程
if (IsScanning)
{
StopScan();
}
// 取消可能正在进行的连接尝试
if (_isConnecting)
{
_isConnecting = false;
_connectingAddress = null;
}
// 先通过BLE协议发送断开命令0x70
Log($"检查BLECommunicationManager: Instance={(BLECommunicationManager.Instance != null ? "" : "null")}");
if (BLECommunicationManager.Instance != null)
{
Log("发送断开命令(0x70)到设备...");
BLECommunicationManager.Instance.Disconnect((success) =>
{
Log($"断开命令发送结果: {(success ? "" : "")}");
// 无论命令是否成功都执行BLE断开
PerformBLEDisconnect(addressToDisconnect);
});
}
else
{
Log("BLECommunicationManager.Instance 为 null跳过0x70命令直接断开BLE");
// 如果没有BLE通信管理器直接断开BLE
PerformBLEDisconnect(addressToDisconnect);
}
}
/// <summary>
/// 执行BLE层断开连接
/// </summary>
private void PerformBLEDisconnect(string addressToDisconnect)
{
Log($"执行BLE断开: {addressToDisconnect}");
BluetoothLEHardwareInterface.DisconnectPeripheral(addressToDisconnect,
(address) =>
{
Log($"BLE断开连接回调: {address}");
}
);
// 立即清理状态
IsConnected = false;
ConnectedDeviceAddress = null;
OnDisconnected?.Invoke(addressToDisconnect);
// 延迟清理
Invoke(nameof(CleanupAfterDisconnect), 0.5f);
}
/// <summary>
/// 断开连接后的清理工作
/// </summary>
private void CleanupAfterDisconnect()
{
Log("执行断开连接后的清理...");
// 确保停止扫描
if (IsScanning)
{
StopScan();
}
// 取消可能冲突的Invoke
CancelInvoke(nameof(StopScan));
CancelInvoke(nameof(DelayedStartScan));
// 清理设备列表,为下次扫描做准备
DiscoveredDevices.Clear();
Log("断开连接清理完成,可以开始新的扫描");
}
/// <summary>
/// 完全重置蓝牙(断开连接并重新初始化)
/// 用于解决断开后无法扫描到设备的问题
/// </summary>
public void ResetBluetooth()
{
Log("开始完全重置蓝牙...");
// 停止扫描
if (IsScanning)
{
StopScan();
}
// 断开连接 - 先发送0x70断开命令再断开BLE连接
if (IsConnected)
{
string addressToDisconnect = ConnectedDeviceAddress;
Log($"重置蓝牙: 正在断开连接 {addressToDisconnect}");
// 先通过BLE协议发送断开命令0x70
if (BLECommunicationManager.Instance != null)
{
Log("重置蓝牙: 发送断开命令(0x70)到设备...");
BLECommunicationManager.Instance.Disconnect((success) =>
{
Log($"重置蓝牙: 断开命令发送结果: {(success ? "" : "")}");
// 无论命令是否成功都执行BLE断开
BluetoothLEHardwareInterface.DisconnectPeripheral(addressToDisconnect, (addr) => { });
});
}
else
{
// 如果没有BLE通信管理器直接断开BLE
BluetoothLEHardwareInterface.DisconnectPeripheral(addressToDisconnect, (addr) => { });
}
IsConnected = false;
ConnectedDeviceAddress = null;
}
// 取消所有Invoke
CancelInvoke();
// 清理设备列表
DiscoveredDevices.Clear();
// 反初始化蓝牙
BluetoothLEHardwareInterface.DeInitialize(() =>
{
IsInitialized = false;
Log("蓝牙已反初始化,准备重新初始化...");
// 延迟重新初始化
Loom.QueueOnMainThread(() =>
{
Invoke(nameof(ReinitializeBluetooth), 1f);
});
});
}
/// <summary>
/// 重新初始化蓝牙(断开连接后使用,不触发自动连接)
/// </summary>
private void ReinitializeBluetooth()
{
Log("重新初始化蓝牙...");
BluetoothLEHardwareInterface.Initialize(true, false,
() =>
{
IsInitialized = true;
Log("蓝牙重新初始化成功,现在可以扫描设备了");
OnInitialized?.Invoke(true);
// 注意:这里不触发自动连接,避免干扰用户操作
},
(error) =>
{
if (error.Contains("Service not found"))
{
Log("蓝牙重新初始化警告,继续...");
IsInitialized = true;
OnInitialized?.Invoke(true);
}
else
{
Log($"蓝牙重新初始化失败: {error}");
OnError?.Invoke($"重新初始化失败: {error}");
}
}
);
}
/// <summary>
/// 反初始化蓝牙
/// </summary>
public void DeInitialize()
{
if (IsConnected)
{
Disconnect();
}
if (IsScanning)
{
StopScan();
}
BluetoothLEHardwareInterface.DeInitialize(() =>
{
IsInitialized = false;
Log("蓝牙已反初始化");
});
}
/// <summary>
/// 添加或更新设备到列表
/// </summary>
private void AddOrUpdateDevice(string address, string name, int rssi)
{
// 调试日志:显示所有发现的设备(包括无名称的)
Log($"扫描到设备: Name='{name}', Address={address}, RSSI={rssi}");
// 查找是否已存在
var existingDevice = DiscoveredDevices.Find(d => d.Address.ToUpper() == address.ToUpper());
if (existingDevice != null)
{
// 更新RSSI
existingDevice.Rssi = rssi;
Log($"更新设备信号: {existingDevice.Name} [{address}] RSSI: {rssi}");
}
else
{
// 过滤掉没有名称的设备
if (string.IsNullOrEmpty(name) || name == "No Name" || name == "Unknown")
{
Log($"过滤无名称设备: [{address}]");
return;
}
// 添加新设备
var newDevice = new BluetoothDevice(address, name, rssi);
DiscoveredDevices.Add(newDevice);
Log($"发现新设备: {name} [{address}] RSSI: {rssi}");
2026-04-28 16:35:51 +08:00
if (aimMac.ToUpper() == address.ToUpper())
{
StopScan();
2026-04-28 16:35:51 +08:00
Connect(address);
}
2026-04-16 14:57:19 +08:00
OnDeviceFound?.Invoke(newDevice);
}
}
/// <summary>
/// 输出日志
/// </summary>
private void Log(string message)
{
Debug.Log($"[BluetoothManager] {message}");
OnLog?.Invoke(message);
}
/// <summary>
/// 通知连接成功并可通信
/// </summary>
private void NotifyConnectedSuccess()
{
Log("蓝牙连接已就绪,可以开始通信");
OnConnectedSuccess?.Invoke();
}
2026-04-28 16:35:51 +08:00
public bool ChangeAimMac(string mac)
2026-04-28 16:35:51 +08:00
{
aimMac = mac;
if (IsConnected && mac.ToUpper() == ConnectedDeviceAddress.ToUpper())
2026-04-28 16:35:51 +08:00
{
return true;
2026-04-28 16:35:51 +08:00
}
else
{
if (IsConnected && mac.ToUpper() != ConnectedDeviceAddress.ToUpper())
{
Disconnect();
StartScan();
}
else
{
StartScan();
}
return false;
2026-04-28 16:35:51 +08:00
}
}
2026-04-16 14:57:19 +08:00
}
}