4

我想沒有它配對到Windows與外圍設備進行通信,我使用BluetoothLEAdvertisementWatcher掃描範圍內的設備。這是我的WatcherOnReceived方法:爲什麼BluetoothLEDevice.GattServices空

async private void WatcherOnReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args) 
    { 
     BluetoothLEDevice device = null; 
     BluetoothDevice basicDevice = null; 
     GattDeviceService services = null; 

     if (args.Advertisement.LocalName != "Nexus 6") 
      return; 

     _watcher.Stop(); 

     device = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress); 
     device.GattServicesChanged += Device_GattServicesChanged; 
     //basicDevice = await BluetoothDevice.FromBluetoothAddressAsync(args.BluetoothAddress); 
     //services = await GattDeviceService.FromIdAsync(device.DeviceId); 

     lock (m_syncObj) 
     { 
      Debug.WriteLine(""); 
      Debug.WriteLine("----------- DEVICE --------------"); 

      Debug.WriteLine(args.ToString()); 

      Debug.WriteLine(args.Advertisement.DataSections.Count); 

      foreach (var item in args.Advertisement.DataSections) 
      { 
       var data = new byte[item.Data.Length]; 
       using (var reader = DataReader.FromBuffer(item.Data)) 
       { 
        reader.ReadBytes(data); 
       } 

       Debug.WriteLine("Manufacturer data: " + BitConverter.ToString(data)); 

       //Debug.WriteLine("Data : " + item.Data.ToString()); 
       //Debug.WriteLine("Data capacity: " + item.Data.Capacity); 
       Debug.WriteLine("Data Type: " + item.DataType); 
      } 

      foreach (var md in args.Advertisement.ManufacturerData) 
      { 
       var data = new byte[md.Data.Length]; 
       using (var reader = DataReader.FromBuffer(md.Data)) 
       { 
        reader.ReadBytes(data); 
       } 
       Debug.WriteLine("Manufacturer data: " + BitConverter.ToString(data)); 
      } 

      foreach (Guid id in args.Advertisement.ServiceUuids) 
      { 
       Debug.WriteLine("UUIDs: " + id.ToString() + " Count: " + args.Advertisement.ServiceUuids.Count); 
       //services = device.GetGattService(id); 
      } 

      Debug.WriteLine("Receive event..."); 
      Debug.WriteLine("BluetoothAddress: " + args.BluetoothAddress.ToString("X")); 
      Debug.WriteLine("Advertisement.LocalName: " + args.Advertisement.LocalName); 
      Debug.WriteLine("AdvertisementType: " + args.AdvertisementType); 
      Debug.WriteLine("RawSignalStrengthInDBm: " + args.RawSignalStrengthInDBm); 

      if (device != null) 
      { 
       Debug.WriteLine("Bluetooth Device: " + device.Name); 
       Debug.WriteLine("Bluetooth Device conn status: " + device.ConnectionStatus); 
       Debug.WriteLine("Bluetooth DeviceId: " + device.DeviceId); 
       Debug.WriteLine("Bluetooth GettServices Count: " + device.GattServices.Count); 
      } 
     } 
    } 

當設備收到我成功地創建從args.BlutoothAddress的BluetoothLEDevice但device.GattServices總是空的,所以我不能使用它們與設備進行通信。是在設備或Windows API中的問題,我還可以嘗試什麼?

回答

4

更新04/17 - CREATORS UPDATE 微軟剛剛更新了他們的藍牙API。我們現在有不成對的BLE設備通信!

他們很少有文檔起來的時刻,但這裏是大大簡化新結構:

BleWatcher = new BluetoothLEAdvertisementWatcher 
{ 
    ScanningMode = BluetoothLEScanningMode.Active 
}; 
BleWatcher.Start(); 

BleWatcher.Received += async (w, btAdv) => { 
    var device = await BluetoothLEDevice.FromBluetoothAddressAsync(btAdv.BluetoothAddress); 
Debug.WriteLine($"BLEWATCHER Found: {device.name}"); 

    // SERVICES!! 
    var gatt = await device.GetGattServicesAsync(); 
    Debug.WriteLine($"{device.Name} Services: {gatt.Services.Count}, {gatt.Status}, {gatt.ProtocolError}"); 

    // CHARACTERISTICS!! 
    var characs = await gatt.Services.Single(s => s.Uuid == SAMPLESERVICEUUID).GetCharacteristicsAsync(); 
    var charac = characs.Single(c => c.Uuid == SAMPLECHARACUUID); 
    await charac.WriteValueAsync(SOMEDATA); 
}; 
現在

好多了。正如我所說的旁邊,目前沒有文件有,我有一個奇怪的問題,在我的回調的ValueChanged停止爲30秒左右後調用,儘管這似乎是一個單獨的範圍界定問題。

更新2 - 一些古怪

後一些更多的新創造者玩弄更新有建築物BLE的應用程序時,需要考慮一些事情。

  • 您不再需要在UI線程上運行藍牙東西。如果沒有配對,似乎沒有任何BLE權限窗口,因此不再需要在UI線程上運行。 您可能會發現你的應用程序停止從設備在一段時間之後接收更新。這是一個範圍問題,在這個範圍內,物體正在被處置,而不應該這樣做。在上面的代碼中,如果您正在傾聽關於Charac的ValueChanged,您可能會遇到此問題。這是因爲GattCharacteristic配置的應該是之前,設置特色作爲一個全球性,而不是依賴於它被複制。 斷開似乎有點破。退出應用程序不會終止連接。因此,請確保使用App.xml.cs的OnSuspended回調來終止您的連接。否則,你會進入一種奇怪的狀態,Windows似乎保持(並且繼續閱讀!!)BLE連接。 它有它的怪癖,但它的工作原理!

  • 這仍然是與Windows通用應用程序的問題,最初的問題是,設備必須配對(不粘結),以便發現GattServices。但是,它們也需要使用Windows設備而不是BLE API來發現。微軟意識到並正在開發一種新的BLE API,它不需要配對,但坦率地說,他們的BLE支持在這個準備就緒之前是無用的。

  • 嘗試控制面板中手動配對的設備,然後再列出的服務。出於某種原因,在Windows通用應用程序,你只能儘管BLE幸福的,你不需要使用其服務之前,該設備配對的優勢之一列出關貿總協定服務配對設備。

可以配對編程但是根據應用正在對這一運行平臺上的設備需要UI提示。因此,在後臺詢問BLE服務是不可行。這需要被修正,因爲它真的阻礙了UWP中的BLE支持。

它的奇怪,但工作!

OLD ANSWER

下面是一些示例代碼工作BLE裝置連接:

private void StartWatcher() 
    { 
     ConnectedDevices = new List<string>(); 

     Watcher = new BluetoothLEAdvertisementWatcher { ScanningMode = BluetoothLEScanningMode.Active }; 
     Watcher.Received += DeviceFound; 

     DeviceWatcher = DeviceInformation.CreateWatcher(); 
     DeviceWatcher.Added += DeviceAdded; 
     DeviceWatcher.Updated += DeviceUpdated; 

     StartScanning(); 
    } 

    private void StartScanning() 
    { 
     Watcher.Start(); 
     DeviceWatcher.Start(); 
    } 

    private async void DeviceFound(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs btAdv) 
    { 
     if (!ConnectedDevices.Contains(btAdv.Advertisement.LocalName) && _devices.Contains(btAdv.Advertisement.LocalName)) 
     { 
      await Dispatcher.RunAsync(CoreDispatcherPriority.Low, async() => 
      { 
       var device = await BluetoothLEDevice.FromBluetoothAddressAsync(btAdv.BluetoothAddress); 
       if (device.GattServices.Any()) 
       { 
        ConnectedDevices.Add(device.Name); 
        device.ConnectionStatusChanged += (sender, args) => 
        { 
         ConnectedDevices.Remove(sender.Name); 
        }; 
        SetupWaxStream(device); 
       } else if (device.DeviceInformation.Pairing.CanPair && !device.DeviceInformation.Pairing.IsPaired) 
       { 
        await device.DeviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.None); 
       } 
      }); 
     } 
    } 

    private async void DeviceAdded(DeviceWatcher watcher, DeviceInformation device) 
    { 
     if (_devices.Contains(device.Name)) 
     { 
      try 
      { 
       var service = await GattDeviceService.FromIdAsync(device.Id); 
       var characteristics = service.GetAllCharacteristics(); 
      } 
      catch 
      { 
       Debug.WriteLine("Failed to open service."); 
      } 
     } 
    } 

    private async void DeviceUpdated(DeviceWatcher watcher, DeviceInformationUpdate update) 
    { 
     var device = await DeviceInformation.CreateFromIdAsync(update.Id); 
     if (_devices.Contains(device.Name)) 
     { 
      try 
      { 
       var service = await GattDeviceService.FromIdAsync(device.Id); 
       var characteristics = service.GetAllCharacteristics(); 
      } 
      catch 
      { 
       Debug.WriteLine("Failed to open service."); 
      } 
     } 
    } 
+0

我嘗試配對的設備,但我仍然得到一個空蓋特服務列表..感謝您的澄清。 –

+0

如果您繼續使用BluetoothLEAdvertismentWatcher觀看,您最終將獲得一組GattServices。我更關注這一點,我已經用一些示例工作代碼更新了這個問題。我必須最終在BLE觀察員拿起服務之前通過DeviceWatcher發現服務。 –

+0

GattServices對我來說也是空的,任何人都管理這個? – abinop