通用视窗应用程序蓝牙支持



我已经尝试过RFCOMM API将图像(jpeg(从UWP(在Windows平板电脑上(发送到其他移动设备(任何移动Android/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();
            }
        }
    }
}

由于我没有看到您的接收器端的代码,因此很难说为什么您无法接收图像文件。要发送和接收图像,您可以参考蓝牙射频通信。本文档包含有关如何使用蓝牙射频通信发送或接收文件的示例代码。虽然示例代码中有一些小错误,但我们可以轻松修复它们。下面是使用示例代码的简单示例,并演示了如何发送和接收图像文件。

将图像文件作为客户端发送

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();
    }
}

将图像文件作为服务器接收

private StreamSocket _socket;
private RfcommServiceProvider _provider;
private async void Initialize()
{
    // 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 += OnConnectionReceivedAsync;
    await listener.BindServiceNameAsync(
        _provider.ServiceId.AsString(),
        SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication);
    // Set the SDP attributes and start advertising
    InitializeServiceSdpAttributes(_provider);
    _provider.StartAdvertising(listener);
}
private const uint SERVICE_VERSION_ATTRIBUTE_ID = 0x0300;
private const byte SERVICE_VERSION_ATTRIBUTE_TYPE = 0x0A;   // UINT32
private const uint SERVICE_VERSION = 200;
private void InitializeServiceSdpAttributes(RfcommServiceProvider provider)
{
    var writer = new Windows.Storage.Streams.DataWriter();
    // First write the attribute type
    writer.WriteByte(SERVICE_VERSION_ATTRIBUTE_TYPE);
    // Then write the data
    writer.WriteUInt32(SERVICE_VERSION);
    var data = writer.DetachBuffer();
    provider.SdpRawAttributes.Add(SERVICE_VERSION_ATTRIBUTE_ID, data);
}
private async void OnConnectionReceivedAsync(
           StreamSocketListener listener,
           StreamSocketListenerConnectionReceivedEventArgs args)
{
    // Stop advertising/listening so that we're only serving one client
    _provider.StopAdvertising();
    listener.Dispose();
    _socket = args.Socket;
    // The client socket is connected. At this point the App can wait for
    // the user to take some action, e.g. click a button to receive a file
    // from the device, which could invoke the Picker and then save the
    // received file to the picked location. The transfer itself would use
    // the Sockets API and not the Rfcomm API, and so is omitted here for
    // brevity.
    var reader = new DataReader(_socket.InputStream);
    bool remoteDisconnection = false;
    // Infinite read buffer loop
    while (true)
    {
        try
        {
            // Based on the protocol we've defined, the first uint is the size of the file name
            uint readLength = await reader.LoadAsync(sizeof(uint));
            // Check if the size of the data is expected (otherwise the remote has already terminated the connection)
            if (readLength < sizeof(uint))
            {
                remoteDisconnection = true;
                break;
            }
            var nameLength = reader.ReadUInt32();
            readLength = await reader.LoadAsync(nameLength);
            // Check if the size of the data is expected (otherwise the remote has already terminated the connection)
            if (readLength < nameLength)
            {
                remoteDisconnection = true;
                break;
            }
            var fileName = reader.ReadString(nameLength);
            // The second uint is the size of the file
            readLength = await reader.LoadAsync(sizeof(uint));
            // Check if the size of the data is expected (otherwise the remote has already terminated the connection)
            if (readLength < sizeof(uint))
            {
                remoteDisconnection = true;
                break;
            }
            var fileLength = reader.ReadUInt32();
            readLength = await reader.LoadAsync(fileLength);
            // Check if the size of the data is expected (otherwise the remote has already terminated the connection)
            if (readLength < fileLength)
            {
                remoteDisconnection = true;
                break;
            }
            var buffer = reader.ReadBuffer(fileLength);
            // Save the received image file to local folder
            var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName);
            await FileIO.WriteBufferAsync(file, buffer);
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(ex.Message);
            break;
        }
    }
    reader.DetachStream();
    reader.Dispose();
    if (remoteDisconnection)
    {
        _socket.Dispose();
    }
}

请注意,上面的示例仅用于演示,它可能具有未处理的异常。有关更多信息,请参阅蓝牙射频通信聊天示例

相关内容

  • 没有找到相关文章