using System; using System.Collections.Generic; using System.Text; namespace Shared.Phone.UserCenter { #if Android public class HdlAndroidBluetoothLogic { #region ■ 变量声明___________________________ /// /// 安卓蓝牙的逻辑 /// private static HdlAndroidBluetoothLogic m_Current = null; /// /// 安卓蓝牙的逻辑 /// public static HdlAndroidBluetoothLogic Current { get { if (m_Current == null) { m_Current = new HdlAndroidBluetoothLogic(); } return m_Current; } } /// /// 当前蓝牙客户端 /// private Blufi.Espressif.BlufiClient nowBlufiClient = null; /// /// 发送状态(0:发送失败 1:发送成功) /// private int sendStatuValue = -1; #endregion #region ■ 蓝牙扫描___________________________ /// /// 搜索蓝牙 /// /// 搜索时间(秒) /// 搜索结束的事件 public void ScanBluetooth(int waitTime, Action> FinishEvent) { //读取蓝牙权限 ((BaseActivity)Application.Activity).SetPermission((result1) => { if (result1 == false) { return; } ((BaseActivity)Application.Activity).SetPermission((result2) => { if (result2 == false) { return; } HdlThreadLogic.Current.RunThread(() => { this.DoScanBluetooth(waitTime, FinishEvent); }); }, "android.permission.ACCESS_FINE_LOCATION"); }, "android.permission.ACCESS_COARSE_LOCATION"); } /// /// 开始搜索蓝牙 /// /// 搜索时间(秒) /// 搜索结束的事件 private void DoScanBluetooth(int waitTime, Action> FinishEvent) { ProgressBar.Show(); var listBluetoothInfo = new List(); var adapter = Android.Bluetooth.BluetoothAdapter.DefaultAdapter; var scanner = adapter.BluetoothLeScanner; if (adapter.IsEnabled == false || scanner == null) { HdlMessageLogic.Current.ShowMassage(ShowMsgType.Tip, "请打开蓝牙"); ProgressBar.Close(); return; } if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.M) { var locationManager = (Android.Locations.LocationManager)Application.Activity.GetSystemService(Android.Content.Context.LocationService); if (locationManager == null) { HdlMessageLogic.Current.ShowMassage(ShowMsgType.Tip, "位置信息(GBS)不可用"); ProgressBar.Close(); return; } if (locationManager.IsProviderEnabled("network") == false || locationManager.IsProviderEnabled("gps") == false) { HdlMessageLogic.Current.ShowMassage(ShowMsgType.Tip, "位置信息(GBS)不可用"); ProgressBar.Close(); return; } } var scanCallback = new BluetoothScanCallback(); scanner.StartScan(null, new Android.Bluetooth.LE.ScanSettings.Builder().SetScanMode(Android.Bluetooth.LE.ScanMode.LowLatency).Build(), scanCallback); System.Threading.Thread.Sleep(waitTime * 1000); scanner.StopScan(scanCallback); adapter.Dispose(); foreach (var data in scanCallback.listData) { listBluetoothInfo.Add(data); } scanCallback.listData.Clear(); ProgressBar.Close(); FinishEvent?.Invoke(listBluetoothInfo); } /// /// 蓝牙的回调对象 /// private class BluetoothScanCallback : Android.Bluetooth.LE.ScanCallback { /// /// 蓝牙列表 /// public List listData = new List(); /// /// 重复检测 /// private List listCheck = new List(); /// /// 蓝牙结果接收 /// /// public override void OnBatchScanResults(IList listResult) { foreach (var result in listResult) { this.AddBluetoothResult(result); } } /// /// 蓝牙结果接收 /// /// /// public override void OnScanResult(Android.Bluetooth.LE.ScanCallbackType callbackType, Android.Bluetooth.LE.ScanResult result) { this.AddBluetoothResult(result); } /// /// 添加蓝牙缓存 /// /// private void AddBluetoothResult(Android.Bluetooth.LE.ScanResult result) { var device = result.Device; if (device == null || listCheck.Contains(device.Address) == true) { return; } listCheck.Add(device.Address); var data = new BluetoothInfo(); data.Name = device.Name; if (data.Name == null) { data.Name = string.Empty; } data.Address = device.Address; data.Device = device; listData.Add(data); } } #endregion #region ■ 蓝牙链接___________________________ /// /// 蓝牙链接(0:失败 1:成功) /// /// 需要链接的蓝牙对象 /// 0:连接失败 1:连接成功 public void ContectBluetooth(BluetoothInfo bluetooth, Action StatuEvent) { try { this.nowBlufiClient = new Blufi.Espressif.BlufiClient(Application.Activity, bluetooth.Device); //一个回调事件 var callback = new InnerGattCallback(); callback.ConnectionStateEvent += (div, newState) => { //OnConnectionStateChange if (div == 1) { if (newState == Android.Bluetooth.ProfileState.Connected) { //链接建立成功 StatuEvent?.Invoke(1); } else if (newState == Android.Bluetooth.ProfileState.Disconnected) { //关闭链接 this.DisContectBluetooth(); StatuEvent?.Invoke(0); } } else if (div == -1) { //关闭链接 this.DisContectBluetooth(); StatuEvent?.Invoke(0); } }; nowBlufiClient.SetGattCallback(callback); //另外一个回调事件 var blufiCall = new BlufiCallbackMain(); blufiCall.StateEvent += (div) => { //-1:异常 1:正常 2:发送数据成功 3:发送数据失败 if (div == -1) { //关闭链接 this.DisContectBluetooth(); StatuEvent?.Invoke(0); } if (div == 2 || div == 3) { sendStatuValue = div == 2 ? 1 : 0; } }; nowBlufiClient.SetBlufiCallback(blufiCall); //执行链接 nowBlufiClient.Connect(); } catch { StatuEvent?.Invoke(0); } } /// /// 先这么定义一个空的继承 /// private class InnerGattCallback : Android.Bluetooth.BluetoothGattCallback { /// /// 状态事件回调(-1:异常 1:OnConnectionStateChange) /// public Action ConnectionStateEvent = null; /// /// 链接状态改变 /// /// /// /// public override void OnConnectionStateChange(Android.Bluetooth.BluetoothGatt gatt, Android.Bluetooth.GattStatus status, Android.Bluetooth.ProfileState newState) { if (status == Android.Bluetooth.GattStatus.Success) { //回调事件 this.ConnectionStateEvent?.Invoke(1, newState); } else { //回调事件 this.ConnectionStateEvent?.Invoke(-1, 0); } } /// /// 成功发现设备的services时,调用此方法 /// /// /// public override void OnServicesDiscovered(Android.Bluetooth.BluetoothGatt gatt, Android.Bluetooth.GattStatus status) { if (status != Android.Bluetooth.GattStatus.Success) { //回调事件 this.ConnectionStateEvent?.Invoke(-1, 0); } } /// /// 应该是写入事件吧 /// /// /// /// public override void OnCharacteristicWrite(Android.Bluetooth.BluetoothGatt gatt, Android.Bluetooth.BluetoothGattCharacteristic characteristic, Android.Bluetooth.GattStatus status) { if (status != Android.Bluetooth.GattStatus.Success) { //回调事件 this.ConnectionStateEvent?.Invoke(-1, 0); } } } /// /// 抄SDK的,我也不知道这个是什么 /// private class BlufiCallbackMain : Blufi.Espressif.BlufiCallback { /// /// 状态事件回调(-1:异常 1:正常 2:发送数据成功 3:发送数据失败) /// public Action StateEvent = null; /// /// 抄SDK的,我也不知道这个是什么 /// /// /// /// /// /// public override void OnGattPrepared(Blufi.Espressif.BlufiClient client, Android.Bluetooth.BluetoothGatt gatt, Android.Bluetooth.BluetoothGattService service, Android.Bluetooth.BluetoothGattCharacteristic writeChar, Android.Bluetooth.BluetoothGattCharacteristic notifyChar) { if (service == null || writeChar == null || notifyChar == null) { StateEvent?.Invoke(-1); return; } try { int mtu = 128; if ((int)Android.OS.Build.VERSION.SdkInt == 29 && Android.OS.Build.Manufacturer.ToLower().StartsWith("samsung") == true) { mtu = 23; } var requestMtu = gatt.RequestMtu(mtu); if (!requestMtu) { //Request mtu failed client.SetPostPackageLengthLimit(20); } StateEvent?.Invoke(1); } catch { StateEvent?.Invoke(-1); return; } } /// /// 手机端发送数据到蓝牙的结果 /// /// /// 0:成功 其他都是失败 /// 手机端发送的数据 public override void OnPostCustomDataResult(Blufi.Espressif.BlufiClient client, int status, byte[] data) { StateEvent?.Invoke(status == 0 ? 2 : 3); } } #endregion #region ■ 蓝牙关闭___________________________ /// /// 关闭蓝牙链接 /// public void DisContectBluetooth() { HdlThreadLogic.Current.RunMain(() => { this.nowBlufiClient?.RequestCloseConnection(); this.nowBlufiClient = null; m_Current = null; }, ShowErrorMode.NO); } #endregion #region ■ 发送数据___________________________ /// /// 发送数据给蓝牙 /// /// 发送的数据 /// 等待时间(秒),如果设置为0,则只要发送不出现异常,直接判定为成功 public bool SendData(string i_data, int waiTime = 0) { if (this.nowBlufiClient == null) { return false; } try { this.sendStatuValue = -1; //发送数据 var byteData = System.Text.Encoding.UTF8.GetBytes(i_data); this.nowBlufiClient.PostCustomData(byteData); 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 ■ 结构体_____________________________ /// /// 蓝牙返回的信息 /// public class BluetoothInfo { /// /// 名字 /// public string Name = string.Empty; /// /// 地址 /// public string Address = string.Empty; /// /// 蓝牙设备 /// public Android.Bluetooth.BluetoothDevice Device = null; } #endregion } #endif }