陈嘉乐
2021-03-30 003abaf86b766eb40ef62300ab0c707774c36ba9
HDL_ON/UI/UI0-Stan/Logic/HdlBluetoothIOSLogic.cs
New file
@@ -0,0 +1,489 @@
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
}