2017-05-19 97 views
1

我想构建两个简单的应用程序,使用蓝牙RFCOMM相互通信。UWP蓝牙RFCOMM FindAllAsync

然而,当我运行客户端应用程序不与_devices = await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.ObexObjectPush));

_devices找到任何设备集合为空。

基于微软文档中的例子,我设法写了这样的东西。

应用接收消息(服务器) - 部署在树莓PI 3.

namespace RaspRFCOMM 
{ 
    public sealed partial class MainPage : Page 
    { 
     private RfcommServiceProvider _provider; 

     public MainPage() 
     { 
      this.InitializeComponent(); 
      this.Initialize(); 
     } 

     private async void Initialize() 
     { 
      msgStatus.Text = "Inicjalizacja..."; 

      // Initialize the provider for the hosted RFCOMM service 
      _provider = await RfcommServiceProvider.CreateAsync(RfcommServiceId.ObexObjectPush); 

      // Create a listener for this service and start listening 
      StreamSocketListener listener = new StreamSocketListener(); 
      listener.ConnectionReceived += OnConnectionReceived; 
      await listener.BindServiceNameAsync(
       _provider.ServiceId.AsString(), 
       SocketProtectionLevel 
        .BluetoothEncryptionAllowNullAuthentication); 

      // Set the SDP attributes and start advertising 
      InitializeServiceSdpAttributes(_provider); 
      _provider.StartAdvertising(listener, true); 
     } 

     const uint SERVICE_VERSION_ATTRIBUTE_ID = 0x0300; 
     const byte SERVICE_VERSION_ATTRIBUTE_TYPE = 0x0A; // UINT32 
     const uint SERVICE_VERSION = 200; 
     private void InitializeServiceSdpAttributes(RfcommServiceProvider provider) 
     { 
      DataWriter writer = new DataWriter(); 

      // First write the attribute type 
      writer.WriteByte(SERVICE_VERSION_ATTRIBUTE_TYPE); 
      // Then write the data 
      writer.WriteUInt32(SERVICE_VERSION); 

      IBuffer data = writer.DetachBuffer(); 
      provider.SdpRawAttributes.Add(SERVICE_VERSION_ATTRIBUTE_ID, data); 
     } 

     private async void OnConnectionReceived(
      StreamSocketListener listener, 
      StreamSocketListenerConnectionReceivedEventArgs args) 
     { 
      msgStatus.Text = "Odczytuje..."; 

      _provider.StopAdvertising(); 
      listener.Dispose(); 

      StreamSocket _socket = args.Socket; 
      StreamReader reader = new StreamReader(_socket.InputStream.AsStreamForRead()); 

      string response = await reader.ReadLineAsync(); 
      msgStatus.Text = "Odczytałem..."; 
      textboxMsg.Text = response + "To odczytalem"; 

     } 
    } 
} 

发送消息:

namespace WinRFCOMM 
{ 
    public sealed partial class MainPage : Page 
    { 
     private RfcommDeviceService _service; 
     private StreamSocket _socket; 
     private DeviceInformationCollection _devices; 
     private StreamWriter _writer; 

     public MainPage() 
     { 
      this.InitializeComponent(); 
      this.Initialize(); 
     } 

     private async void Initialize() 
     { 
      msgStatus.Text = "Inicjalizacja..."; 
      _devices = await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.ObexObjectPush)); 

      this.PopulateDevicesListview(_devices); 
      msgStatus.Text = "Oczekiwanie na wybór..."; 
     } 

     private void PopulateDevicesListview(DeviceInformationCollection devices) 
     { 
      foreach (DeviceInformation di in devices) 
      { 
       String deviceInfo = di.Name + " - " + di.Id; 
       lvDevices.Items.Add(deviceInfo); 
      } 
     } 

     private void btnConnect_Click(object sender, RoutedEventArgs e) 
     { 
      var selected = lvDevices.SelectedIndex; 
      if (selected != -1) 
      { 
       ConnectToRFC(_devices[selected]); 
      } 
     } 

     private async void ConnectToRFC(DeviceInformation selectedDevice) 
     { 
      _service = await RfcommDeviceService.FromIdAsync(selectedDevice.Id); 

      _socket = new StreamSocket(); 

      await _socket.ConnectAsync(
       _service.ConnectionHostName, 
       _service.ConnectionServiceName, 
       SocketProtectionLevel 
        .BluetoothEncryptionAllowNullAuthentication); 

      msgStatus.Text = "Połączono..."; 

      _writer = new StreamWriter(_socket.OutputStream.AsStreamForWrite()); 
      _writer.WriteLineAsync("Test"); 
     } 
    } 
} 

两者都清单文件设置是这样的:

<Capabilities> 
    <Capability Name="internetClient" /> 
    <Capability Name="internetClientServer" /> 
    <Capability Name="privateNetworkClientServer" /> 
    <DeviceCapability Name="bluetooth" /> 
    </Capabilities> 

我非常感谢任何帮助,因为我已经坚持了近2天。

+0

不知怎的,它开始工作,但我不知道为什么。我会让我知道什么时候我会解决这个问题。 – br33f

+0

它可以在没有配对的情况下工作吗? –

回答

0

该问题不在代码中。

在运行此RFCOMM样本之前,您需要先配对两台设备。由于

使用RfcommDeviceService.GetDeviceSelector *功能,以帮助 生成可用于列举配对设备所需服务的 实例的AQS查询。

编号:Send a file as a client

+0

谢谢您的回答,但配对设备尚未解决问题。列表设备与RfcommServiceId.ObexObjectPush选择器仍然无法工作。它显示带有BluetoothDevice.GetDeviceSelector()的树莓设备,但是它会在RfcommDeviceService.FromIdAsync()上引发“无法找到元素”异常。 – br33f

0

我发现this论坛帖子里面我度过它。

我的问题是试图使用我发现的配对DeviceInformation作为我的RFCOMM连接点。

对于RFCOMM,你会需要你的AppManifest的样子:

<DeviceCapability Name="bluetooth.rfcomm"> 

    <Device Id="any"> 

    <Function Type ="name:serialPort"/> 

    </Device> 

</DeviceCapability> 

而不是仅仅有名称为“蓝牙”。