From d2666457d16f6171785596a8a9cb2fb9fb35f84b Mon Sep 17 00:00:00 2001
From: JLChen <551775569@qq.com>
Date: 星期五, 16 四月 2021 18:03:54 +0800
Subject: [PATCH] 2021-4-16-1
---
HDL_ON/UI/UI0-Stan/Logic/HdlBluetoothAndroidLogic.cs | 590 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 590 insertions(+), 0 deletions(-)
diff --git a/HDL_ON/UI/UI0-Stan/Logic/HdlBluetoothAndroidLogic.cs b/HDL_ON/UI/UI0-Stan/Logic/HdlBluetoothAndroidLogic.cs
new file mode 100644
index 0000000..b416038
--- /dev/null
+++ b/HDL_ON/UI/UI0-Stan/Logic/HdlBluetoothAndroidLogic.cs
@@ -0,0 +1,590 @@
+锘縰sing Shared;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace HDL_ON.Stan
+{
+#if __Android__
+ 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 Blufi.Espressif.BlufiClient nowBlufiClient = null;
+ /// <summary>
+ /// 鎺ユ敹浜嬩欢
+ /// </summary>
+ private Action<string> ReceiveEvent = null;
+ /// <summary>
+ /// 鍙戦�佺姸鎬�(0:鍙戦�佸け璐� 1:鍙戦�佹垚鍔�)
+ /// </summary>
+ private int sendStatuValue = -1;
+
+ #endregion
+
+ #region 鈻� 钃濈墮鎵�闇�鍔熻兘妫�娴媉__________________
+
+ /// <summary>
+ /// 妫�娴嬫槸鍚﹁兘澶熸悳绱㈣摑鐗�(鍐呴儴浼氬脊鍑篗sg妗�,鍥犱负鍐呴儴闇�瑕佹娴嬬郴缁熸潈闄�,鎵�浠ュ弬鏁伴噰鐢ㄥ洖璋冪殑鏂瑰紡)
+ /// </summary>
+ /// <param name="resultEvent">妫�娴嬬粨鏋滀簨浠�</param>
+ public void CheckCanScanBluetooth(Action<bool> resultEvent)
+ {
+ var adapter = Android.Bluetooth.BluetoothAdapter.DefaultAdapter;
+ var scanner = adapter.BluetoothLeScanner;
+ if (adapter.IsEnabled == false || scanner == null)
+ {
+ HdlMessageLogic.Current.ShowMassage(ShowMsgType.Tip, Language.StringByID(StringId.PleaseTurnOnBluetooth));
+ resultEvent?.Invoke(false);
+ 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)
+ {
+ //浣嶇疆淇℃伅(GBS)涓嶅彲鐢�
+ HdlMessageLogic.Current.ShowMassage(ShowMsgType.Tip, Language.StringByID(StringId.GbsIsNotAvailable));
+ resultEvent?.Invoke(false);
+ return;
+ }
+ if (locationManager.IsProviderEnabled("network") == false)
+ {
+ HdlMessageLogic.Current.ShowMassage(ShowMsgType.Tip, Language.StringByID(StringId.NetworkIsNotAvailable));
+ resultEvent?.Invoke(false);
+ return;
+ }
+ if (locationManager.IsProviderEnabled("gps") == false)
+ {
+ //浣嶇疆淇℃伅(GBS)涓嶅彲鐢�
+ HdlMessageLogic.Current.ShowMassage(ShowMsgType.Tip, Language.StringByID(StringId.GbsIsNotAvailable));
+ resultEvent?.Invoke(false);
+ return;
+ }
+ }
+ //妫�娴嬭摑鐗欓渶瑕佺殑鏉冮檺
+ ((BaseActivity)Application.Activity).SetPermission((result1) =>
+ {
+ if (result1 == false)
+ {
+ resultEvent?.Invoke(false);
+ return;
+ }
+ ((BaseActivity)Application.Activity).SetPermission((result2) =>
+ {
+ if (result2 == false)
+ {
+ resultEvent?.Invoke(false);
+ return;
+ }
+ //鍏ㄩ儴閫氳繃
+ resultEvent?.Invoke(true);
+
+ }, "android.permission.ACCESS_FINE_LOCATION");
+
+ }, "android.permission.ACCESS_COARSE_LOCATION");
+ }
+
+ #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 listBluetoothInfo = new List<BluetoothInfo>();
+
+ BluetoothScanCallback scanCallback = null;
+ Android.Bluetooth.BluetoothAdapter adapter = null;
+ Android.Bluetooth.LE.BluetoothLeScanner scanner = null;
+
+ //浠ラ槻涓囦竴,钃濈墮閮戒涪鍦ㄤ富绾跨▼涓繍琛�
+ HdlThreadLogic.Current.RunMain(() =>
+ {
+ adapter = Android.Bluetooth.BluetoothAdapter.DefaultAdapter;
+ scanner = adapter.BluetoothLeScanner;
+
+ scanCallback = new BluetoothScanCallback();
+ scanner.StartScan(null, new Android.Bluetooth.LE.ScanSettings.Builder().SetScanMode(Android.Bluetooth.LE.ScanMode.LowLatency).Build(), scanCallback);
+ }, ShowErrorMode.NO);
+
+ //绛夊緟
+ System.Threading.Thread.Sleep(waitTime * 1000);
+
+ HdlThreadLogic.Current.RunMain(() =>
+ {
+ scanner.StopScan(scanCallback);
+ adapter.Dispose();
+
+ foreach (var data in scanCallback.listData)
+ {
+ listBluetoothInfo.Add(data);
+ }
+ scanCallback.listData.Clear();
+
+ FinishEvent?.Invoke(listBluetoothInfo);
+ });
+ }
+
+ /// <summary>
+ /// 钃濈墮鐨勫洖璋冨璞�
+ /// </summary>
+ private class BluetoothScanCallback : Android.Bluetooth.LE.ScanCallback
+ {
+ /// <summary>
+ /// 钃濈墮鍒楄〃
+ /// </summary>
+ public List<BluetoothInfo> listData = new List<BluetoothInfo>();
+ /// <summary>
+ /// 閲嶅妫�娴�
+ /// </summary>
+ private List<string> listCheck = new List<string>();
+
+ /// <summary>
+ /// 钃濈墮缁撴灉鎺ユ敹
+ /// </summary>
+ /// <param name="listResult"></param>
+ public override void OnBatchScanResults(IList<Android.Bluetooth.LE.ScanResult> listResult)
+ {
+ foreach (var result in listResult)
+ {
+ this.AddBluetoothResult(result);
+ }
+ }
+
+ /// <summary>
+ /// 钃濈墮缁撴灉鎺ユ敹
+ /// </summary>
+ /// <param name="callbackType"></param>
+ /// <param name="result"></param>
+ public override void OnScanResult(Android.Bluetooth.LE.ScanCallbackType callbackType, Android.Bluetooth.LE.ScanResult result)
+ {
+ this.AddBluetoothResult(result);
+ }
+
+ /// <summary>
+ /// 娣诲姞钃濈墮缂撳瓨
+ /// </summary>
+ /// <param name="result"></param>
+ 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 鈻� 钃濈墮閾炬帴___________________________
+
+ /// <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
+ {
+ this.nowBlufiClient = new Blufi.Espressif.BlufiClient(Application.Activity, bluetooth.Device);
+
+ //涓�涓洖璋冧簨浠�
+ var callback = new InnerGattCallback();
+ callback.ConnectionStateEvent += (div, newState) =>
+ {
+ if (div == 1)
+ {
+ if (newState == Android.Bluetooth.ProfileState.Connected)
+ {
+ //閾炬帴寤虹珛鎴愬姛
+ connectEvent?.Invoke(true);
+ //鍙�氱煡涓�娆�
+ connectEvent = null;
+ }
+ else if (newState == Android.Bluetooth.ProfileState.Disconnected)
+ {
+ //鍏抽棴閾炬帴
+ this.DisContectBluetooth();
+ connectEvent?.Invoke(false);
+ //鍙�氱煡涓�娆�
+ connectEvent = null;
+ }
+ }
+ else if (div == -1)
+ {
+ //鍏抽棴閾炬帴
+ this.DisContectBluetooth();
+ connectEvent?.Invoke(false);
+ //鍙�氱煡涓�娆�
+ connectEvent = null;
+ }
+ };
+ nowBlufiClient.SetGattCallback(callback);
+
+ //鍙﹀涓�涓洖璋冧簨浠�
+ var blufiCall = new BlufiCallbackMain();
+ blufiCall.StateEvent += (div, data) =>
+ {
+ //-1:寮傚父 1:姝e父 2:鍙戦�佹暟鎹垚鍔� 3:鍙戦�佹暟鎹け璐�
+ if (div == StatuEnum.A寮傚父)
+ {
+ //鍏抽棴閾炬帴
+ this.DisContectBluetooth();
+ connectEvent?.Invoke(false);
+ //鍙�氱煡涓�娆�
+ 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);
+ }
+ };
+ nowBlufiClient.SetBlufiCallback(blufiCall);
+ //鎵ц閾炬帴
+ nowBlufiClient.Connect();
+ }
+ catch
+ {
+ connectEvent?.Invoke(false);
+ connectEvent = null;
+ }
+ });
+ }
+
+ /// <summary>
+ /// 鍏堣繖涔堝畾涔変竴涓┖鐨勭户鎵�
+ /// </summary>
+ private class InnerGattCallback : Android.Bluetooth.BluetoothGattCallback
+ {
+ /// <summary>
+ /// 鐘舵�佷簨浠跺洖璋�(-1:寮傚父 1:OnConnectionStateChange)
+ /// </summary>
+ public Action<int,Android.Bluetooth.ProfileState> ConnectionStateEvent = null;
+ /// <summary>
+ /// 閾炬帴鐘舵�佹敼鍙�
+ /// </summary>
+ /// <param name="gatt"></param>
+ /// <param name="status"></param>
+ /// <param name="newState"></param>
+ 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);
+ }
+ }
+
+ /// <summary>
+ /// 鎴愬姛鍙戠幇璁惧鐨剆ervices鏃讹紝璋冪敤姝ゆ柟娉�
+ /// </summary>
+ /// <param name="gatt"></param>
+ /// <param name="status"></param>
+ public override void OnServicesDiscovered(Android.Bluetooth.BluetoothGatt gatt, Android.Bluetooth.GattStatus status)
+ {
+ if (status != Android.Bluetooth.GattStatus.Success)
+ {
+ //鍥炶皟浜嬩欢
+ this.ConnectionStateEvent?.Invoke(-1, 0);
+ }
+ }
+
+ /// <summary>
+ /// 搴旇鏄啓鍏ヤ簨浠跺惂
+ /// </summary>
+ /// <param name="gatt"></param>
+ /// <param name="characteristic"></param>
+ /// <param name="status"></param>
+ 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);
+ }
+ }
+ }
+
+ /// <summary>
+ /// 鎶凷DK鐨勶紝鎴戜篃涓嶇煡閬撹繖涓槸浠�涔�
+ /// </summary>
+ private class BlufiCallbackMain : Blufi.Espressif.BlufiCallback
+ {
+ /// <summary>
+ /// 鐘舵�佷簨浠跺洖璋� 褰撶涓�涓弬鏁颁负"A钃濈墮鍙嶉"鏃�,绗簩涓弬鏁颁负钃濈墮杩斿洖鐨勪俊鎭�
+ /// </summary>
+ public Action<StatuEnum, string> StateEvent = null;
+
+ /// <summary>
+ /// 鎶凷DK鐨勶紝鎴戜篃涓嶇煡閬撹繖涓槸浠�涔�
+ /// </summary>
+ /// <param name="client"></param>
+ /// <param name="gatt"></param>
+ /// <param name="service"></param>
+ /// <param name="writeChar"></param>
+ /// <param name="notifyChar"></param>
+ 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(StatuEnum.A寮傚父, null);
+ 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(StatuEnum.A姝e父, null); ;
+ }
+ catch
+ {
+ StateEvent?.Invoke(StatuEnum.A寮傚父, null);
+ return;
+ }
+ }
+
+ /// <summary>
+ /// 鎵嬫満绔彂閫佹暟鎹埌钃濈墮鐨勭粨鏋�
+ /// </summary>
+ /// <param name="client"></param>
+ /// <param name="status">0:鎴愬姛 鍏朵粬閮芥槸澶辫触</param>
+ /// <param name="data">鎵嬫満绔彂閫佺殑鏁版嵁</param>
+ public override void OnPostCustomDataResult(Blufi.Espressif.BlufiClient client, int status, byte[] data)
+ {
+ StateEvent?.Invoke(status == 0 ? StatuEnum.A鍙戦�佹垚鍔� : StatuEnum.A鍙戦�佸け璐�, null);
+ }
+
+ /// <summary>
+ /// 钃濈墮鍥炲鐨勭粨鏋�
+ /// </summary>
+ /// <param name="client"></param>
+ /// <param name="status">0:鎴愬姛 鍏朵粬閮芥槸澶辫触</param>
+ /// <param name="data">钃濈墮鍥炲鐨勬暟鎹�</param>
+ public override void OnReceiveCustomData(Blufi.Espressif.BlufiClient client, int status, byte[] data)
+ {
+ if (status == 0)
+ {
+ var receiveData = System.Text.Encoding.UTF8.GetString(data);
+ StateEvent?.Invoke(StatuEnum.A钃濈墮鍙嶉, receiveData);
+ }
+ }
+ }
+
+ #endregion
+
+ #region 鈻� 钃濈墮鍏抽棴___________________________
+
+ /// <summary>
+ /// 鍏抽棴钃濈墮閾炬帴
+ /// </summary>
+ public void DisContectBluetooth()
+ {
+ HdlThreadLogic.Current.RunMain(() =>
+ {
+ this.nowBlufiClient?.RequestCloseConnection();
+ this.nowBlufiClient = null;
+
+ m_Current = 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.nowBlufiClient == null)
+ {
+ return false;
+ }
+
+ try
+ {
+ this.sendStatuValue = -1;
+ HdlThreadLogic.Current.RunMain(() =>
+ {
+ //鍙戦�佹暟鎹�
+ var byteData = System.Text.Encoding.UTF8.GetBytes(i_data);
+ this.nowBlufiClient.PostCustomData(byteData);
+
+ }, 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 鈻� 缁撴瀯浣揰____________________________
+
+ /// <summary>
+ /// 钃濈墮杩斿洖鐨勪俊鎭�
+ /// </summary>
+ public class BluetoothInfo
+ {
+ /// <summary>
+ /// 鍚嶅瓧(姝ゅ悕瀛椾笉浼歯ull,濡傛灉瀹冩湰韬槸null,鍙細鏄痵tring.empty)
+ /// </summary>
+ public string Name = string.Empty;
+ /// <summary>
+ /// 鍦板潃
+ /// </summary>
+ public string Address = string.Empty;
+ /// <summary>
+ /// 钃濈墮璁惧
+ /// </summary>
+ public Android.Bluetooth.BluetoothDevice Device = null;
+ }
+
+ /// <summary>
+ /// 鐘舵�佹灇涓�
+ /// </summary>
+ private enum StatuEnum
+ {
+ A寮傚父 = -1,
+ A姝e父 = 1,
+ A鍙戦�佹垚鍔� = 2,
+ A鍙戦�佸け璐� = 3,
+ A钃濈墮鍙嶉 = 4
+ }
+
+ #endregion
+ }
+#endif
+}
+
--
Gitblit v1.8.0