通用Windows应用程序蓝牙支持

时间:2017-05-09 06:29:47

标签: c# sockets bluetooth uwp rfcomm

我已尝试使用RFCOMM API将图像(jpeg)从UWP(在Windows平板电脑上)发送到其他移动设备(任何移动设备/ Windows)。

在我的应用程序中,套接字创建成功并且写入套接字输出流将文件大小的值作为返回值(认为它也是成功的)。

但是在接收方,它没有显示任何接受/接收,也无法在该设备中看到该文件。

我还在应用清单中添加了功能。

<DeviceCapability Name="bluetooth.rfcomm">
    <Device Id="any">
        <Function Type="serviceId:00001101-0000-1000-8000-00805F9B34FB" />
    </Device>
</DeviceCapability>

C#代码:

async void Initialize()
{
    var services = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(
    RfcommDeviceService.GetDeviceSelector(
        RfcommServiceId.ObexObjectPush));

    if (services.Count > 0)
    {
        var service = await RfcommDeviceService.FromIdAsync(services[0].Id);

        if (SupportsProtection(service))
        {
            _service = service;

            Windows.Devices.Enumeration.DeviceAccessStatus accessStatus = await _service.Device.RequestAccessAsync();

            if (accessStatus.Equals(Windows.Devices.Enumeration.DeviceAccessStatus.DeniedByUser))
            {
                await dialog.ShowAsync();
                return;
            }

            dialog = new MessageDialog(_service.Device.Name);
            await dialog.ShowAsync();

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

            var picker = new FileOpenPicker();
            picker.ViewMode = PickerViewMode.Thumbnail;
            picker.SuggestedStartLocation =
            PickerLocationId.PicturesLibrary;
            picker.FileTypeFilter.Add(".jpeg");
            picker.FileTypeFilter.Add(".jpg");
            picker.FileTypeFilter.Add(".png");
            var file = await picker.PickSingleFileAsync();
            if (file != null)
            {
                var stream = await file.OpenStreamForReadAsync();
                byte[] bytes = new byte[(int)stream.Length];
                stream.Read(bytes, 0, (int)stream.Length);
                IBuffer buffer = bytes.AsBuffer();
                uint test = await _socket.OutputStream.WriteAsync(buffer);
                await _socket.OutputStream.FlushAsync();
                _socket.Dispose();

                dialog = new MessageDialog("Result :" + test.ToString());
                await dialog.ShowAsync();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

由于我没有看到接收方的代码,因此很难说为什么您无法接收图像文件。要发送和接收图像,您可以参考Bluetooth RFCOMM。本文档包含有关如何使用蓝牙RFCOMM发送或接收文件的示例代码。尽管示例代码中存在一些重大错误,但我们可以轻松修复它们。以下是一个简单的示例,使用示例代码并演示如何发送和接收图像文件。

以客户身份发送图片文件

C# String.Format()

接收图像文件作为服务器

private RfcommDeviceService _service;
private StreamSocket _socket;

private async void Initialize()
{
    // Enumerate devices with the object push service
    var services =
        await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(
            RfcommDeviceService.GetDeviceSelector(
                RfcommServiceId.ObexObjectPush));

    if (services.Count > 0)
    {
        // Initialize the target Bluetooth BR device
        var service = await RfcommDeviceService.FromIdAsync(services[0].Id);

        // Check that the service meets this App's minimum requirement
        if (SupportsProtection(service) && await IsCompatibleVersion(service))
        {
            _service = service;

            // Create a socket and connect to the target
            _socket = new StreamSocket();
            await _socket.ConnectAsync(
                _service.ConnectionHostName,
                _service.ConnectionServiceName,
                SocketProtectionLevel
                    .BluetoothEncryptionAllowNullAuthentication);

            // The socket is connected. At this point the App can wait for
            // the user to take some action, e.g. click a button to send a
            // file to the device, which could invoke the Picker and then
            // send the picked file. The transfer itself would use the
            // Sockets API and not the Rfcomm API, and so is omitted here for
            // brevity.
        }
    }
}

// This App requires a connection that is encrypted but does not care about
// whether its authenticated.
private bool SupportsProtection(RfcommDeviceService service)
{
    switch (service.ProtectionLevel)
    {
        case SocketProtectionLevel.PlainSocket:
            if ((service.MaxProtectionLevel == SocketProtectionLevel
                    .BluetoothEncryptionWithAuthentication)
                || (service.MaxProtectionLevel == SocketProtectionLevel
                    .BluetoothEncryptionAllowNullAuthentication))
            {
                // The connection can be upgraded when opening the socket so the
                // App may offer UI here to notify the user that Windows may
                // prompt for a PIN exchange.
                return true;
            }
            else
            {
                // The connection cannot be upgraded so an App may offer UI here
                // to explain why a connection won't be made.
                return false;
            }
        case SocketProtectionLevel.BluetoothEncryptionWithAuthentication:
            return true;

        case SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication:
            return true;
    }
    return false;
}

// This App relies on CRC32 checking available in version 2.0 of the service.
private const uint SERVICE_VERSION_ATTRIBUTE_ID = 0x0300;

private const byte SERVICE_VERSION_ATTRIBUTE_TYPE = 0x0A;   // UINT32
private const uint MINIMUM_SERVICE_VERSION = 200;

private async System.Threading.Tasks.Task<bool> IsCompatibleVersion(RfcommDeviceService service)
{
    var attributes = await service.GetSdpRawAttributesAsync(Windows.Devices.Bluetooth.BluetoothCacheMode.Uncached);
    var attribute = attributes[SERVICE_VERSION_ATTRIBUTE_ID];
    var reader = DataReader.FromBuffer(attribute);

    // The first byte contains the attribute' s type
    byte attributeType = reader.ReadByte();
    if (attributeType == SERVICE_VERSION_ATTRIBUTE_TYPE)
    {
        // The remainder is the data
        uint version = reader.ReadUInt32();
        return version >= MINIMUM_SERVICE_VERSION;
    }
    return false;
}

// Click a button to send a image file to the device
private async void Button_Click(object sender, RoutedEventArgs e)
{
    var picker = new FileOpenPicker();
    picker.ViewMode = PickerViewMode.Thumbnail;
    picker.SuggestedStartLocation =
    PickerLocationId.PicturesLibrary;
    picker.FileTypeFilter.Add(".jpeg");
    picker.FileTypeFilter.Add(".jpg");
    picker.FileTypeFilter.Add(".png");
    var file = await picker.PickSingleFileAsync();
    if (file != null)
    {
        DataWriter writer = null;
        try
        {
            writer = new DataWriter(_socket.OutputStream);

            writer.WriteUInt32((uint)file.Name.Length);
            writer.WriteString(file.Name);

            var buffer = await FileIO.ReadBufferAsync(file);
            writer.WriteUInt32(buffer.Length);
            writer.WriteBuffer(buffer);

            await writer.StoreAsync();
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(ex.Message);
        }

        writer.DetachStream();
        writer.Dispose();
    }
}

请注意以上示例仅用于演示,可能有未处理的异常。有关详细信息,请参阅Bluetooth RFCOMM chat sample