New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | |
| | | namespace HDL_ON.Stan |
| | | { |
| | | #if __IOS__ |
| | | /// <summary> |
| | | /// IOS蓝牙的逻辑 |
| | | /// </summary> |
| | | public class HdlBluetoothLogic |
| | | { |
| | | #region ■ 变量声明___________________________ |
| | | |
| | | /// <summary> |
| | | /// 安卓蓝牙的逻辑 |
| | | /// </summary> |
| | | private static HdlBluetoothLogic m_Current = null; |
| | | /// <summary> |
| | | /// 安卓蓝牙的逻辑 |
| | | /// </summary> |
| | | public static HdlBluetoothLogic Current |
| | | { |
| | | get |
| | | { |
| | | if (m_Current == null) |
| | | { |
| | | m_Current = new HdlBluetoothLogic(); |
| | | } |
| | | return m_Current; |
| | | } |
| | | } |
| | | /// <summary> |
| | | /// 我也不知道这是什么东西 |
| | | /// </summary> |
| | | private HdlBlufi.HdlBluWi hdlBluWiShare; |
| | | /// <summary> |
| | | /// 我也不知道这是什么东西 |
| | | /// </summary> |
| | | private HdlBlufi.BlufiClient blufiClient; |
| | | /// <summary> |
| | | /// 接收事件 |
| | | /// </summary> |
| | | private Action<string> ReceiveEvent = null; |
| | | /// <summary> |
| | | /// 发送状态(0:发送失败 1:发送成功) |
| | | /// </summary> |
| | | private int sendStatuValue = -1; |
| | | /// <summary> |
| | | /// 蓝牙是否打开 |
| | | /// </summary> |
| | | private bool IsBlufiOpen = false; |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 初始化___________________________ |
| | | |
| | | /// <summary> |
| | | /// 初始化 |
| | | /// </summary> |
| | | private bool InitHdlBlufi() |
| | | { |
| | | if (hdlBluWiShare != null) { return true; } |
| | | |
| | | try |
| | | { |
| | | this.hdlBluWiShare = HdlBlufi.HdlBluWi.Share(); |
| | | this.blufiClient = new HdlBlufi.BlufiClient(); |
| | | |
| | | blufiClient.CentralManagerDelete = new BlueCBCentralManagerDelegate(); |
| | | //添加回调事件 |
| | | ((BlueCBCentralManagerDelegate)blufiClient.CentralManagerDelete).StateEvent += (div, data) => |
| | | { |
| | | //-1:异常 1:正常 |
| | | if (div == StatuEnum.A异常) |
| | | { |
| | | //蓝牙没有打开 |
| | | this.IsBlufiOpen = false; |
| | | } |
| | | else if (div == StatuEnum.A正常) |
| | | { |
| | | //蓝牙打开着 |
| | | this.IsBlufiOpen = true; |
| | | } |
| | | }; |
| | | |
| | | blufiClient.BlufiDelegate = new BlueWifiDelegate(); |
| | | return true; |
| | | } |
| | | catch { return false; } |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 蓝牙所需功能检测___________________ |
| | | |
| | | /// <summary> |
| | | /// 检测是否能够搜索蓝牙(内部会弹出Msg框,因为内部需要检测系统权限,所以参数采用回调的方式) |
| | | /// </summary> |
| | | /// <param name="resultEvent">检测结果事件</param> |
| | | public void CheckCanScanBluetooth(Action<bool> resultEvent) |
| | | { |
| | | try |
| | | { |
| | | //先初始化 |
| | | if (this.InitHdlBlufi() == false) |
| | | { |
| | | resultEvent?.Invoke(false); |
| | | //请打开蓝牙 |
| | | HdlMessageLogic.Current.ShowMassage(ShowMsgType.Tip, Shared.Language.StringByID(StringId.PleaseTurnOnBluetooth)); |
| | | return; |
| | | } |
| | | |
| | | if (this.IsBlufiOpen == true) |
| | | { |
| | | //因为是一直监听着,所以如果是true,直接返回 |
| | | resultEvent?.Invoke(this.IsBlufiOpen); |
| | | return; |
| | | } |
| | | |
| | | HdlThreadLogic.Current.RunThread(() => |
| | | { |
| | | //ios需要监听才能够获得蓝牙的状态 |
| | | System.Threading.Thread.Sleep(500); |
| | | if (this.IsBlufiOpen == false) |
| | | { |
| | | //请打开蓝牙 |
| | | HdlMessageLogic.Current.ShowMassage(ShowMsgType.Tip, Shared.Language.StringByID(StringId.PleaseTurnOnBluetooth)); |
| | | } |
| | | HdlThreadLogic.Current.RunMain(() => |
| | | { |
| | | resultEvent?.Invoke(this.IsBlufiOpen); |
| | | }); |
| | | }, ShowErrorMode.NO); |
| | | } |
| | | catch |
| | | { |
| | | resultEvent?.Invoke(false); |
| | | //请打开蓝牙 |
| | | HdlMessageLogic.Current.ShowMassage(ShowMsgType.Tip, Shared.Language.StringByID(StringId.PleaseTurnOnBluetooth)); |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 蓝牙扫描___________________________ |
| | | |
| | | /// <summary> |
| | | /// 搜索蓝牙 |
| | | /// </summary> |
| | | /// <param name="waitTime">搜索时间(秒)</param> |
| | | /// <param name="FinishEvent">搜索结束的事件</param> |
| | | public void ScanBluetooth(int waitTime, Action<List<BluetoothInfo>> FinishEvent) |
| | | { |
| | | HdlThreadLogic.Current.RunMain(() => |
| | | { |
| | | //再次检测是否能够搜索蓝牙 |
| | | this.CheckCanScanBluetooth((result) => |
| | | { |
| | | if (result == true) |
| | | { |
| | | HdlThreadLogic.Current.RunThread(() => |
| | | { |
| | | //开始搜索蓝牙 |
| | | this.DoScanBluetooth(waitTime, FinishEvent); |
| | | }); |
| | | } |
| | | }); |
| | | }); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 开始搜索蓝牙 |
| | | /// </summary> |
| | | /// <param name="waitTime">搜索时间(秒)</param> |
| | | /// <param name="FinishEvent">搜索结束的事件</param> |
| | | private void DoScanBluetooth(int waitTime, Action<List<BluetoothInfo>> FinishEvent) |
| | | { |
| | | //蓝牙列表 |
| | | var listData = new List<BluetoothInfo>(); |
| | | //重复检测 |
| | | var listCheck = new List<string>(); |
| | | //实现蓝牙接收事件 |
| | | var ReceiveBlufiDeviceEvent = new HdlBlufi.FBYBleDeviceBackBlock((arg0) => |
| | | { |
| | | var address = arg0.Uuid.ToString(); |
| | | if (listCheck.Contains(address) == false) |
| | | { |
| | | listCheck.Add(address); |
| | | var data = new BluetoothInfo(); |
| | | data.Address = address; |
| | | data.Name = arg0.Name == null ? string.Empty : arg0.Name; |
| | | listData.Add(data); |
| | | } |
| | | }); |
| | | HdlThreadLogic.Current.RunMain(() => |
| | | { |
| | | //开启蓝牙搜索 |
| | | this.hdlBluWiShare.StartScan(ReceiveBlufiDeviceEvent); |
| | | }, ShowErrorMode.NO); |
| | | System.Threading.Thread.Sleep(waitTime * 1000); |
| | | |
| | | HdlThreadLogic.Current.RunMain(() => |
| | | { |
| | | //关闭蓝牙搜索 |
| | | this.hdlBluWiShare.StopScan(); |
| | | ReceiveBlufiDeviceEvent = null; |
| | | |
| | | }, ShowErrorMode.NO); |
| | | //回调事件 |
| | | FinishEvent?.Invoke(listData); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 蓝牙链接___________________________ |
| | | |
| | | /// <summary> |
| | | /// 蓝牙链接(false:连接失败 true:连接成功) |
| | | /// </summary> |
| | | /// <param name="bluetooth">需要链接的蓝牙对象</param> |
| | | /// <param name="connectEvent">因为需要对方反馈,所以使用回调(链接结果 false:连接失败 true:连接成功)</param> |
| | | public void ContectBluetooth(BluetoothInfo bluetooth, Action<bool> connectEvent) |
| | | { |
| | | HdlThreadLogic.Current.RunMain(() => |
| | | { |
| | | try |
| | | { |
| | | //添加事件 |
| | | ((BlueWifiDelegate)blufiClient.BlufiDelegate).StateEvent += (div, data) => |
| | | { |
| | | //-1:异常 1:正常 2:发送数据成功 3:发送数据失败 |
| | | if (div == StatuEnum.A异常) |
| | | { |
| | | //关闭链接 |
| | | this.DisContectBluetooth(); |
| | | connectEvent?.Invoke(false); |
| | | //只通知一次 |
| | | connectEvent = null; |
| | | } |
| | | else if (div == StatuEnum.A正常) |
| | | { |
| | | //链接建立成功 |
| | | connectEvent?.Invoke(true); |
| | | //只通知一次 |
| | | connectEvent = null; |
| | | } |
| | | else if (div == StatuEnum.A发送成功 || div == StatuEnum.A发送失败) |
| | | { |
| | | sendStatuValue = div == StatuEnum.A发送成功 ? 1 : 0; |
| | | } |
| | | else if (div == StatuEnum.A蓝牙反馈) |
| | | { |
| | | //蓝牙返回的结果 |
| | | this.ReceiveEvent?.Invoke(data); |
| | | } |
| | | }; |
| | | //执行链接 |
| | | this.blufiClient.Connect(bluetooth.Address); |
| | | } |
| | | catch |
| | | { |
| | | connectEvent?.Invoke(false); |
| | | connectEvent = null; |
| | | } |
| | | }); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 蓝牙关闭___________________________ |
| | | |
| | | /// <summary> |
| | | /// 关闭蓝牙链接 |
| | | /// </summary> |
| | | public void DisContectBluetooth() |
| | | { |
| | | HdlThreadLogic.Current.RunMain(() => |
| | | { |
| | | this.blufiClient?.Close(); |
| | | this.blufiClient = null; |
| | | this.hdlBluWiShare = null; |
| | | |
| | | }, ShowErrorMode.NO); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 摧毁 |
| | | /// </summary> |
| | | public void Dispone() |
| | | { |
| | | //关闭蓝牙链接 |
| | | this.DisContectBluetooth(); |
| | | this.ReceiveEvent = null; |
| | | m_Current = null; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 发送数据___________________________ |
| | | |
| | | /// <summary> |
| | | /// 发送数据给蓝牙 |
| | | /// </summary> |
| | | /// <param name="i_data">发送的数据</param> |
| | | /// <param name="waiTime">等待时间(秒),如果设置为0,则只要发送不出现异常,直接判定为成功</param> |
| | | public bool SendData(string i_data, int waiTime = 0) |
| | | { |
| | | if (this.blufiClient == null) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | try |
| | | { |
| | | this.sendStatuValue = -1; |
| | | HdlThreadLogic.Current.RunMain(() => |
| | | { |
| | | //发送数据 |
| | | var data = new Foundation.NSData(); |
| | | data = i_data; |
| | | blufiClient.PostCustomData(data); |
| | | |
| | | }, ShowErrorMode.NO); |
| | | |
| | | if (waiTime == 0) { return true; } |
| | | |
| | | waiTime *= 5; |
| | | while (this.sendStatuValue == -1 && waiTime > 0) |
| | | { |
| | | System.Threading.Thread.Sleep(200); |
| | | waiTime--; |
| | | } |
| | | return this.sendStatuValue == 1; |
| | | } |
| | | catch { return false; } |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 一般方法___________________________ |
| | | |
| | | /// <summary> |
| | | /// 添加蓝牙的接收事件 |
| | | /// </summary> |
| | | /// <param name="i_ReceiveEvent">蓝牙接收事件</param> |
| | | public void AddReceiveEvent(Action<string> i_ReceiveEvent) |
| | | { |
| | | this.ReceiveEvent = i_ReceiveEvent; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 移除蓝牙的接收事件 |
| | | /// </summary> |
| | | public void RemoveReceiveEvent() |
| | | { |
| | | this.ReceiveEvent = null; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 系统蓝牙回调_______________________ |
| | | |
| | | private class BlueWifiDelegate : HdlBlufi.BlufiDelegate |
| | | { |
| | | /// <summary> |
| | | /// 状态事件回调 当第一个参数为"A蓝牙反馈"时,第二个参数为蓝牙返回的信息 |
| | | /// </summary> |
| | | public Action<StatuEnum, string> StateEvent = null; |
| | | |
| | | public override void Blufi_didNegotiateSecurity(HdlBlufi.BlufiClient client, HdlBlufi.BlufiStatusCode status) |
| | | { |
| | | //Console.WriteLine("Blufi_didNegotiateSecurity"); |
| | | } |
| | | |
| | | public override void Blufi_didPostCustomData(HdlBlufi.BlufiClient client, Foundation.NSData data, HdlBlufi.BlufiStatusCode status) |
| | | { |
| | | if (status == HdlBlufi.BlufiStatusCode.Success) |
| | | { |
| | | //发送蓝牙数据成功 |
| | | StateEvent?.Invoke(StatuEnum.A发送成功, null); |
| | | } |
| | | else |
| | | { |
| | | //发送蓝牙数据失败 |
| | | StateEvent?.Invoke(StatuEnum.A发送失败, null); |
| | | } |
| | | } |
| | | |
| | | public override void Blufi_didReceiveDeviceScanResponse(HdlBlufi.BlufiClient client, HdlBlufi.BlufiScanResponse[] scanResults, HdlBlufi.BlufiStatusCode status) |
| | | { |
| | | //Console.WriteLine("Blufi_didReceiveDeviceScanResponse"); |
| | | } |
| | | |
| | | public override void Blufi_didReceiveDeviceVersionResponse(HdlBlufi.BlufiClient client, HdlBlufi.BlufiVersionResponse response, HdlBlufi.BlufiStatusCode status) |
| | | { |
| | | //Console.WriteLine("Blufi_didReceiveDeviceVersionResponse"); |
| | | } |
| | | |
| | | public override void Blufi_didPostConfigureParams(HdlBlufi.BlufiClient client, HdlBlufi.BlufiStatusCode status) |
| | | { |
| | | //Console.WriteLine("Blufi_didPostConfigureParams"); |
| | | } |
| | | |
| | | public override void Blufi_didReceiveCustomData(HdlBlufi.BlufiClient client, Foundation.NSData data, HdlBlufi.BlufiStatusCode status) |
| | | { |
| | | //接收蓝牙发送过来的数据 |
| | | StateEvent?.Invoke(StatuEnum.A蓝牙反馈, data.ToString()); |
| | | } |
| | | |
| | | public override void Blufi_didReceiveDeviceStatusResponse(HdlBlufi.BlufiClient client, HdlBlufi.BlufiStatusResponse response, HdlBlufi.BlufiStatusCode status) |
| | | { |
| | | //Console.WriteLine("Blufi_didReceiveDeviceStatusResponse"); |
| | | } |
| | | |
| | | public override void Blufi_didReceiveError(HdlBlufi.BlufiClient client, nint errCode) |
| | | { |
| | | //Console.WriteLine("Blufi_didReceiveError"); |
| | | } |
| | | |
| | | public override void Blufi_gattPrepared(HdlBlufi.BlufiClient client, HdlBlufi.BlufiStatusCode status, CoreBluetooth.CBService service, CoreBluetooth.CBCharacteristic writeChar, CoreBluetooth.CBCharacteristic notifyChar) |
| | | { |
| | | if (status == HdlBlufi.BlufiStatusCode.Success) |
| | | { |
| | | //蓝牙连接成功 |
| | | StateEvent?.Invoke(StatuEnum.A正常, null); |
| | | } |
| | | else |
| | | { |
| | | //蓝牙连接失败 |
| | | StateEvent?.Invoke(StatuEnum.A异常, null); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private class BlueCBCentralManagerDelegate : CoreBluetooth.CBCentralManagerDelegate |
| | | { |
| | | /// <summary> |
| | | /// 状态事件回调 |
| | | /// </summary> |
| | | public Action<StatuEnum, string> StateEvent = null; |
| | | |
| | | public override void UpdatedState(CoreBluetooth.CBCentralManager central) |
| | | { |
| | | //只要没有打开蓝牙,都算异常处理 |
| | | if (central.State == CoreBluetooth.CBCentralManagerState.PoweredOn) |
| | | { |
| | | StateEvent?.Invoke(StatuEnum.A正常, null); |
| | | } |
| | | else |
| | | { |
| | | StateEvent?.Invoke(StatuEnum.A异常, null); |
| | | } |
| | | } |
| | | } |
| | | #endregion |
| | | |
| | | #region ■ 结构体_____________________________ |
| | | |
| | | /// <summary> |
| | | /// 蓝牙返回的信息 |
| | | /// </summary> |
| | | public class BluetoothInfo |
| | | { |
| | | /// <summary> |
| | | /// 名字(此名字不会null,如果它本身是null,只会是string.empty) |
| | | /// </summary> |
| | | public string Name = string.Empty; |
| | | /// <summary> |
| | | /// 地址 |
| | | /// </summary> |
| | | public string Address = string.Empty; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 状态枚举 |
| | | /// </summary> |
| | | private enum StatuEnum |
| | | { |
| | | A异常 = -1, |
| | | A正常 = 1, |
| | | A发送成功 = 2, |
| | | A发送失败 = 3, |
| | | A蓝牙反馈 = 4 |
| | | } |
| | | |
| | | #endregion |
| | | } |
| | | #endif |
| | | } |