2017-05-09 7 views
1

RFCOMM API를 사용하여 UWP (Windows 태블릿)에서 다른 모바일 (모든 모바일 안드로이드/윈도우)으로 이미지 (jpeg)를 보내려고했습니다.유니버셜 윈도우 응용 프로그램 블루투스 지원

내 응용 프로그램에서는 소켓 작성이 성공하고 socket outputstream에 쓰면 파일 크기 값이 반환 값으로 제공됩니다 (성공이라고 생각하십시오).

수신자 측에서는 수신/수신을 표시하지 않으므로 해당 장치에서 파일을 볼 수 없습니다.

또한 앱 매니페스트에 기능을 추가했습니다.

<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

나는 당신의 수신 측의 코드를 보지 못했다, 그것은 당신이 이미지 파일을 수신 할 수없는 이유를 말하기 어렵다. 이미지를 보내고 받으려면 Bluetooth RFCOMM을 참조하십시오. 이 문서에는 Bluetooth RFCOMM을 사용하여 파일을 보내거나받는 방법에 대한 예제 코드가 들어 있습니다. 예제 코드에는 약간의 실수가 있지만 쉽게 수정할 수 있습니다. 다음은 간단한 예제이며 예제 코드를 사용하고 이미지 파일을 보내고받는 방법을 보여줍니다. 클라이언트

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

단지 데모,이 처리되지 않은 예외가있을 수 있습니다 샘플 이상주의와 같은 이미지 파일을받을 수 있습니다. 자세한 내용은 Bluetooth RFCOMM chat sample을 참조하십시오.

+0

수신자를 쓰고 싶지 않습니다. 난 그냥 연결된 모든 장치에 파일을 보내고 싶었어요. 어떤 모바일 (안드로이드 또는 창문)에 내 Windows 태블릿처럼. – syam218