UWP蓝牙RFCOMM FindAllAsync

时间:2017-05-19 07:41:31

标签: bluetooth uwp rfcomm windowsiot

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

但是,当我运行客户端应用时,它找不到任何带有_devices = await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.ObexObjectPush));

的设备

_devices collection为空。

根据微软文档中的示例,我设法写了这样的东西。

应用程序接收消息(服务器) - 部署在Raspberry 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 :(得分:0)

问题不在于代码。

在运行此RFCOMM示例之前,您首先需要配对两个设备。因为

  

使用RfcommDeviceService.GetDeviceSelector *函数来提供帮助   生成可用于枚举配对设备的AQS查询   所需服务的实例。

参考:Send a file as a client

答案 1 :(得分:0)

我找到this论坛帖子,让我通过它。

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

对于rfcomm,您需要使用AppManifest:

implementation 'play-services-ads-lite:11.2.0'

而不只是将名称称为“蓝牙”。