using InTheHand.Net;
|
using InTheHand.Net.Bluetooth;
|
using InTheHand.Net.Sockets;
|
using System.Text;
|
|
namespace IBox.WinFrmUI
|
{
|
public class BluetoothHelper
|
{
|
#region 单例
|
|
private static BluetoothHelper _Instance;
|
private static readonly object locker = new object();
|
|
public static BluetoothHelper GetInstance()
|
{
|
if (_Instance == null)
|
{
|
lock (locker)
|
{
|
// 如果类的实例不存在则创建,否则直接返回
|
if (_Instance == null)
|
{
|
_Instance = new BluetoothHelper();
|
}
|
}
|
}
|
return _Instance;
|
}
|
|
private int _length = 1;
|
|
#endregion 单例
|
|
#region 信息状态
|
|
/// <summary>
|
/// 信息状态
|
/// </summary>
|
/// <param name="srMessage"> 接收、发送信息、本地信息 </param>
|
/// <param name="content"> 信息内容 </param>
|
public delegate void ShowMessReturn(string content);
|
|
public event ShowMessReturn SMR;
|
|
public void OnSysMessage(string content)
|
{
|
if (SMR != null) SMR(content);
|
}
|
|
#endregion 信息状态
|
|
#region 属性定义
|
|
private const int BUFLEN = 1024; // 数据接收缓冲区大小
|
private bool IsRun = false;
|
private BluetoothAddress bthAddr = null;
|
private BluetoothClient myClient = null;
|
private List<BluetoothClient> LstClient = new List<BluetoothClient>();
|
private BluetoothListener blthListener = null;
|
private Thread listenThread = null;//监听线程
|
|
private List<BluetoothDeviceInfo> LstBluetooth = null;
|
|
#endregion 属性定义
|
|
#region 处理方法
|
|
public BluetoothHelper()
|
{
|
try
|
{
|
var radio = BluetoothRadio.Default;//获取当前PC的蓝牙适配器
|
IsRun = (null != radio);
|
}
|
catch
|
{
|
}
|
if (!IsRun) OnSysMessage("无可用蓝牙");
|
}
|
|
~BluetoothHelper()
|
{
|
if (null != blthListener) blthListener.Stop();
|
if (null != LstClient)
|
{
|
foreach (var itm in LstClient)
|
{
|
if (null != itm)
|
itm.Close();
|
}
|
}
|
IsRun = false;
|
}
|
|
/// <summary>
|
/// 搜索蓝牙
|
/// </summary>
|
public List<BluetoothDeviceInfo> SearchBluetooth()
|
{
|
LstBluetooth = new List<BluetoothDeviceInfo>(); //搜索到的蓝牙的集合
|
if (!IsRun) OnSysMessage("无可用蓝牙");
|
else
|
{
|
BluetoothClient client = new BluetoothClient();
|
BluetoothRadio radio = BluetoothRadio.Default; //获取蓝牙适配器
|
radio.Mode = RadioMode.Connectable;
|
var devices = client.DiscoverDevices();//搜索蓝牙 10秒钟
|
LstBluetooth.AddRange(devices);
|
//OnSysMessage("搜索蓝牙完成");
|
}
|
|
return LstBluetooth;
|
}
|
|
/// <summary>
|
/// 连接蓝牙,蓝牙名称
|
/// </summary>
|
/// <param name="bluetoothName"></param>
|
public void SetBluetoothByName(string bluetoothName)
|
{
|
try
|
{
|
if (null == LstBluetooth) return;
|
var curBluetooth = LstBluetooth.Find(o => o.DeviceName == bluetoothName);
|
if (null != curBluetooth) bthAddr = curBluetooth.DeviceAddress;
|
NewConnect();
|
}
|
catch (Exception ex)
|
{
|
OnSysMessage("error:" + ex.ToString());
|
}
|
}
|
|
/// <summary>
|
/// 连接蓝牙,蓝牙地址(十六进制字符串)
|
/// </summary>
|
/// <param name="hexAddr"></param>
|
public void SetBluetooth(string hexAddr)
|
{
|
try
|
{
|
var byTmp = HexToByte(hexAddr);
|
Array.Reverse(byTmp);// 反转数组
|
SetBluetooth(byTmp);
|
}
|
catch (Exception ex)
|
{
|
OnSysMessage("error:" + ex.ToString());
|
}
|
}
|
|
/// <summary>
|
/// 连接蓝牙,蓝牙地址
|
/// </summary>
|
/// <param name="addr"></param>
|
public void SetBluetooth(byte[] addr)
|
{
|
try
|
{
|
bthAddr = new BluetoothAddress(addr);
|
NewConnect();
|
}
|
catch (Exception ex)
|
{
|
OnSysMessage("error:" + ex.ToString());
|
}
|
}
|
|
/// <summary>
|
/// 连接蓝牙,蓝牙地址
|
/// </summary>
|
/// <param name="laddr"></param>
|
public void SetBluetooth(long laddr)
|
{
|
try
|
{
|
bthAddr = new BluetoothAddress(laddr);
|
NewConnect();
|
}
|
catch (Exception ex)
|
{
|
OnSysMessage("error:" + ex.ToString());
|
}
|
}
|
|
/// <summary>
|
/// 连接蓝牙
|
/// </summary>
|
private void NewConnect()
|
{
|
if (!IsRun) OnSysMessage("无可用蓝牙");
|
else if (null != bthAddr)
|
{
|
var mGUID = BluetoothService.Handsfree;
|
|
if (null != myClient) myClient.Close();
|
myClient = new BluetoothClient();
|
//myClient.Connect(bthAddr,mGUID);
|
var be = new BluetoothEndPoint(bthAddr, BluetoothService.SerialPort);
|
myClient.Connect(be);
|
|
ReceiveDataThread(myClient, false);
|
//OnSysMessage("发起连接");
|
}
|
}
|
|
/// <summary>
|
/// 发送数据,文本
|
/// </summary>
|
/// <param name="sData"></param>
|
public void SendData(string sData)
|
{
|
if (!string.IsNullOrEmpty(sData) && (sData.Contains("getbase") || sData.Contains("alarm")))
|
_length = 1;
|
else
|
_length = 100;
|
var byTmp = Encoding.UTF8.GetBytes(sData);
|
SendData(byTmp);
|
}
|
|
/// <summary>
|
/// 发送数据,byte
|
/// </summary>
|
/// <param name="sData"></param>
|
public void SendData(byte[] sData)
|
{
|
try
|
{
|
if (!IsRun) OnSysMessage("无可用蓝牙");
|
else if (null == sData || sData.Length < 1) OnSysMessage("发送数据不能为空");
|
else
|
{
|
var sendCnt = 0;
|
if (null != LstClient && LstClient.Count > 0)
|
{
|
foreach (var itm in LstClient)
|
{
|
if (null != itm && itm.Connected)
|
{
|
var bls = itm.GetStream();
|
bls.Write(sData, 0, sData.Length);
|
bls.Flush();
|
sendCnt++;
|
}
|
}
|
}
|
|
if (sendCnt < 1 && (null == myClient || !myClient.Connected)) NewConnect(); // 重连机制
|
if (null != myClient && myClient.Connected)
|
{
|
var bls = myClient.GetStream();
|
bls.Write(sData, 0, sData.Length);
|
bls.Flush();
|
sendCnt++;
|
}
|
|
//OnSysMessage(string.Format("连接{0}发送{1}个字节", sendCnt, sData.Length));
|
}
|
}
|
catch (Exception ex)
|
{
|
OnSysMessage("error:" + ex.ToString());
|
}
|
}
|
|
/// <summary>
|
/// 监听蓝牙连接请求
|
/// </summary>
|
public void ListenerData()
|
{
|
//OnSysMessage("蓝牙启动监听:" + IsRun);
|
if (null != listenThread) listenThread.Abort();
|
listenThread = new Thread(new ThreadStart(() =>
|
{
|
if (IsRun)
|
{
|
var mGUID = BluetoothService.Handsfree;
|
blthListener = new BluetoothListener(mGUID);
|
blthListener.Start();
|
|
while (IsRun)
|
{
|
var newClient = blthListener.AcceptBluetoothClient();
|
//OnSysMessage("蓝牙链接:" + newClient.RemoteMachineName);
|
ReceiveDataThread(newClient);
|
}
|
}
|
}));
|
listenThread.IsBackground = true;
|
listenThread.Start();
|
}
|
|
/// <summary>
|
/// 蓝牙数据接收线程
|
/// </summary>
|
/// <param name="client"></param>
|
/// <param name="isInList"></param>
|
private void ReceiveDataThread(BluetoothClient client, bool isInList = true)
|
{
|
lock (LstClient) { if (isInList) LstClient.Add(client); }
|
var th = new Thread(new ThreadStart(() =>
|
{
|
ReceiveData(client);
|
lock (LstClient) LstClient.Remove(client);
|
}));
|
th.IsBackground = true;
|
th.Start();
|
}
|
|
public void Close()
|
{
|
if (myClient != null && myClient.Connected)
|
{
|
myClient.Close();
|
myClient.Dispose();
|
myClient = null;
|
}
|
}
|
|
/// <summary>
|
/// 数据接收
|
/// </summary>
|
/// <param name="client"></param>
|
private void ReceiveData(BluetoothClient client)
|
{
|
try
|
{
|
var sl = new List<string>();
|
var st = new byte[0];
|
|
while (client != null && client.Connected)
|
{
|
var peerStream = client.GetStream();
|
byte[] buffer = new byte[1];
|
peerStream.Read(buffer, 0, 1);
|
st = st.Concat(buffer).ToArray();
|
var receive = Encoding.UTF8.GetString(st).ToString();
|
if (receive.Contains("[&end&]"))
|
{
|
var c = Encoding.UTF8.GetString(st).ToString();
|
st = new byte[0];
|
OnSysMessage(c);
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
// OnSysMessage("error:" + ex.ToString());
|
}
|
}
|
|
#endregion 处理方法
|
|
#region 辅助方法
|
|
/// <summary>
|
/// 十六进制转byte[],无分割符
|
/// </summary>
|
public byte[] HexToByte(string strHex)
|
{
|
byte[] byTmp = new byte[0];
|
if (string.IsNullOrEmpty(strHex) || (strHex.Length % 2) > 0) return byTmp;
|
|
try
|
{
|
var len = strHex.Length / 2;
|
byTmp = new byte[len];
|
for (int i = 0; i < len; i++)
|
{
|
var phex = strHex.Substring(2 * i, 2);
|
byTmp[i] = Convert.ToByte(phex, 16);
|
}
|
}
|
catch (Exception ex)
|
{
|
byTmp = new byte[0];
|
OnSysMessage("error:" + ex.ToString());
|
}
|
return byTmp;
|
}
|
|
#endregion 辅助方法
|
}
|
}
|