using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Markup; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Threading; using Windows.Devices.Bluetooth.GenericAttributeProfile; using WpfBleApp.Ble; using WpfBleApp.Model; using WpfBleApp.Utils; namespace WpfBleApp { /// /// 蓝牙通信页面 /// public partial class CommPage : Page { private readonly CommPageViewModel ViewModel = new CommPageViewModel(); private readonly ObservableCollection Logs = new ObservableCollection(); private int LogCount; bool isSending = false; public CommPage() { InitializeComponent(); listBoxLog.ItemsSource = Logs; } /// /// 连接设备 /// /// /// private void buttonConnect_Click(object sender, RoutedEventArgs e) { if (ViewModel.BleDevice.IsConnected) { ViewModel.BleDevice.Disconnect(); } else { ViewModel.BleDevice.Connect(); } } int[] result = GetRandom(50); /// /// 发送数据 /// /// /// private async void buttonSend_Click(object sender, RoutedEventArgs e) { if (buttonSend.Content.ToString() == "发送") { byte[] data = IntArrToByteArr(result); //byte[] data = ViewModel.TxDataHex.ToData();//待发送的数据 //bool success = await ViewModel.BleDevice.Write(data); int time = 2;//间隔 isSending = true; Time_Send(time, data); buttonSend.Content = "停止"; } else if (buttonSend.Content.ToString() == "停止") { isSending = false; buttonSend.Content = "发送"; } //byte[] data = ViewModel.TxDataHex.ToData();//待发送的数据 //bool success = await ViewModel.BleDevice.Write(data); //for (int i = 0; i < data.Length; i++) //{ // Console.WriteLine(data[i]); //} //if (success) //{ // AddLog("发送成功 >>> " + data.ToHex()); //} } /// /// 定时发送数据 /// /// /// private async void Time_Send(int time, byte[] message) { while (isSending) { //调用发送的那个方法 bool success = await ViewModel.BleDevice.Write(message); if (success) { AddLog("发送成功 >>> " + message.ToHex()); } //间隔 await Task.Delay(1000 * time); } } /// /// 收到的数据 /// /// /// private void BleDevice_CharacteristicValueChanged(GattCharacteristic sender, byte[] args) { AddLog($"收到数据 <<< {args.ToHex()}"); } /// /// 读取设备名称 /// /// /// private async void buttonRead_Click(object sender, RoutedEventArgs e) { byte[] data = await ViewModel.BleDevice.Read(Uuids.GenericAccess, Uuids.DeviceName); if (data != null) { AddLog($"读取的设备名称: {Encoding.UTF8.GetString(data)}"); } } public CommPage(BleDevice device) : this() { ViewModel.BleDevice = device; ViewModel.BleDevice.CharacteristicValueChanged += BleDevice_CharacteristicValueChanged; ViewModel.BleDevice.ConnectionStateChanged += BleDevice_ConnectionStateChanged; DataContext = ViewModel; device.Connect(); } private void BleDevice_ConnectionStateChanged(BleDevice sender, bool args) { if (args) { AddLog("连接成功!"); } else { AddLog("连接已断开!"); } UpdateConnectButton(args); } /// /// 更新连接按钮状态信息 /// /// private void UpdateConnectButton(bool connected) { buttonConnect.Dispatcher.Invoke(delegate { if (connected) { buttonConnect.Content = "断开连接"; buttonConnect.Background = new SolidColorBrush(Color.FromRgb(199, 0, 6)); buttonConnect.Foreground = new SolidColorBrush(Colors.White); } else { buttonConnect.Content = "连接设备"; buttonConnect.Background = new SolidColorBrush(Colors.LightGray); buttonConnect.Foreground = new SolidColorBrush(Colors.Black); } }); } private void AddLog(string msg) { listBoxLog.Dispatcher.Invoke(delegate { if (LogCount > 500) { Logs.RemoveAt(0); } Logs.Add($"{DateTime.Now:HH:mm:ss.fff} - {msg}"); LogCount++; }); } /// /// int数组转化为byte数组 /// /// /// public static byte[] IntArrToByteArr(int[] intArr) { int intSize = sizeof(int) * intArr.Length; byte[] bytArr = new byte[intSize]; //申请一块非托管内存 IntPtr ptr = Marshal.AllocHGlobal(intSize); //复制int数组到该内存块 Marshal.Copy(intArr, 0, ptr, intArr.Length); //复制回byte数组 Marshal.Copy(ptr, bytArr, 0, bytArr.Length); //释放申请的非托管内存 Marshal.FreeHGlobal(ptr); return bytArr; } /// /// 获得无重复随机数组 /// /// 上限n /// 返回随机数组 static int[] GetRandom(int n) { //容器A和B int[] arryA = new int[n]; int[] arryB = new int[n]; //填充容器a for (int i = 0; i < arryA.Length; i++) { arryA[i] = i + 1; } //随机对象 Random r = new Random(); //最后一个元素的索引 如n=100,end=99 int end = n - 1; for (int i = 0; i < n; i++) { //生成随机数 因为随机的是索引 所以从0到100取,end=100 //一个大于等于 minValue 且小于 maxValue 的 32 位带符号整数,即:返回的值范围包括 minValue 但不包括 maxValue。 //如果 minValue 等于 maxValue,则返回 minValue int minValue = 0; int maxValue = end + 1; int ranIndex = r.Next(minValue, maxValue); //把随机数放在容器B中 arryB[i] = arryA[ranIndex]; //用最后一个元素覆盖取出的元素 arryA[ranIndex] = arryA[end]; //缩减随机数生成的范围 end--; } //返回生成的随机数组 return arryB; } } }