之前在做比赛时遇到了这个问题,需要使用UWP连接蓝牙设备接收数据,官方文档上面的使用PeerFinder,然后用await streamSocket.ConnectAsync(info.HostName, “1”);连接,总是出现值不在范围内,最后终于被我找到了解决方案
我们可以用搜索所有设备过滤出蓝牙设备的方法:
var devices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(GattServiceUuids.GenericAccess));
var service = await GattDeviceService.FromIdAsync(devices[0].Id);
serviceUUID出来后可以自己找特征值。
具体代码如下:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.Devices.Bluetooth;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Enumeration;
using Windows.Foundation;
using Windows.Networking;
using Windows.Networking.Proximity;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
using Windows.UI.Core;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
// “空白页”项模板在 http://go.microsoft.com/fwlink/?LinkId=234238 上提供
namespace MyApp
{
///
/// 可用于自身或导航至 Frame 内部的空白页。
///
public sealed partial class BindDevicePage : Page
{
public BindDevicePage()
{
this.InitializeComponent();
if (App.IsHardwareButtonsAPIPresent)
{
btn_back.Visibility = Visibility.Collapsed;
}
else
{
btn_back.Visibility = Visibility.Visible;
}
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
await ScanDevice();
}
private async void ABB_Refresh_OnClicked(object sender, RoutedEventArgs e)
{
await ScanDevice();
}
private async void ABB_Accept_OnClicked(object sender, RoutedEventArgs e)
{
try
{
if (await ConnectToDevice() == false)
return;
if (await FindService() == false)
return;
if (await FindCharacteristic() == false)
return;
getValue();
}
catch (Exception exc)
{
Debug.WriteLine("BindDevicePage ABB_Accept_OnClicked: " + exc.Message);
}
MessageDialog dialog = new MessageDialog("Bind Device successfully!");
dialog.Commands.Add(new UICommand("OK", cmd => { }, commandId: 0));
IUICommand result = await dialog.ShowAsync();
if ((int)result.Id == 0)
{
if (this.Frame.CanGoBack)
{
this.Frame.GoBack();
}
}
}
DeviceInformationCollection bleDevices;
BluetoothLEDevice _device;
IReadOnlyList _services;
GattDeviceService _service;
GattCharacteristic _characteristic;
public string str;
bool _notificationRegistered;
private async Task<int> ScanDevice()
{
try
{
//查找所有设备
bleDevices = await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelector());
Debug.WriteLine("Found " + bleDevices.Count + " device(s)");
if (bleDevices.Count == 0)
{
await new MessageDialog("No BLE Devices found - make sure you've paired your device").ShowAsync();
//跳转到蓝牙设置界面
await Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings-bluetooth:", UriKind.RelativeOrAbsolute));
}
deviceList.ItemsSource = bleDevices;
}
catch (Exception ex)
{
//if((uint)ex.HResult == 0x8007048F)
//{
// await new MessageDialog("Bluetooth is turned off!").ShowAsync();
//}
await new MessageDialog("Failed to find BLE devices: " + ex.Message).ShowAsync();
}
return bleDevices.Count;
}
private async Task<bool> ConnectToDevice()
{
try
{
for (int i = 0; i < bleDevices.Count; i++)
{
//VICTOR是设备名称,改成你自己的就行
if (bleDevices[i].Name == "VICTOR")
{
_device = await BluetoothLEDevice.FromIdAsync(bleDevices[i].Id);
_services = _device.GattServices;
Debug.WriteLine("Found Device: " + _device.Name);
return true;
}
}
}
catch (Exception ex)
{
await new MessageDialog("Connection failed: " + ex.Message).ShowAsync();
return false;
}
await new MessageDialog("Unable to find device VICTOR - has it been paired?").ShowAsync();
return true;
}
private async Task<bool> FindService()
{
foreach (GattDeviceService s in _services)
{
Debug.WriteLine("Found Service: " + s.Uuid);
if (s.Uuid == new Guid("0000fff0-0000-1000-8000-00805f9b34fb"))
{
_service = s;
return true;
}
}
await new MessageDialog("Unable to find VICTOR Service 0000fff0").ShowAsync();
return false;
}
private async Task<bool> FindCharacteristic()
{
foreach (var c in _service.GetCharacteristics(new Guid("0000fff1-0000-1000-8000-00805f9b34fb")))
{
//"unauthorized access" without proper permissions
_characteristic = c;
Debug.WriteLine("Found characteristic: " + c.Uuid);
return true;
}
//IReadOnlyList characteristics = _service.GetAllCharacteristics();
await new MessageDialog("Could not find characteristic or permissions are incorrrect").ShowAsync();
return false;
}
public async void getValue()
{
//注册消息监听器
await RegisterNotificationAsync();
GattReadResult x = await _characteristic.ReadValueAsync();
if (x.Status == GattCommunicationStatus.Success)
{
str = ParseString(x.Value);
Debug.WriteLine(str);
}
}
public static string ParseString(IBuffer buffer)
{
DataReader reader = DataReader.FromBuffer(buffer);
return reader.ReadString(buffer.Length);
}
//接受蓝牙数据并校验进行上传
public async void CharacteristicValueChanged_Handler(GattCharacteristic sender, GattValueChangedEventArgs obj)
{
str = ParseString(obj.CharacteristicValue);
Debug.WriteLine(str);
//TODO str就是蓝牙数据,你可以做自己想做的了
}
public async Task RegisterNotificationAsync()
{
if (_notificationRegistered)
{
return;
}
GattCommunicationStatus writeResult;
if (((_characteristic.CharacteristicProperties & GattCharacteristicProperties.Notify) != 0))
{
_characteristic.ValueChanged +=
new TypedEventHandler(CharacteristicValueChanged_Handler);
writeResult = await _characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(
GattClientCharacteristicConfigurationDescriptorValue.Notify);
_notificationRegistered = true;
}
}
private async void ABB_Bluetooth_OnClicked(object sender, RoutedEventArgs e)
{
await Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings-bluetooth:"));
}
private void btn_back_onClicked(object sender, RoutedEventArgs e)
{
if (this.Frame.CanGoBack)
{
this.Frame.GoBack();
}
}
}
}