BLE扫描间隔Windows 10

使用Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher时,有没有办法在Windows 10上调整BLE广告扫描间隔Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher ? 在Android上扫描时,我每100毫秒看到一次广告,但在使用C#的Windows 10上,我每隔700毫秒就会收到一次BluetoothLEAdvertisementWatcher.Received事件。

我猜不会。

扫描参数硬编码为118.125 ms的扫描间隔和18.125 ms的扫描窗口。

这就是为什么你只获得所有数据包的1/7(因为18.125 / 118.125是~1 / 7)。

但是,您可以使用DeviceIoControl来进行更低级别的操作。 这是一个例子。 您必须与BluetoothLEAdvertisementWatcher并行运行(例如BetterScanner.StartScanner(0, 29, 29) )。 如果两个扫描仪同时处于活动状态,Windows似乎总是选择“最佳”参数。

DeviceIoControl永远不会返回,所以我在一个单独的线程中运行它。 如果您需要能够取消扫描,则必须使用重叠的io才能执行CancelIoEx。 此代码不检查错误,因此请注意。

 using System; using System.Runtime.InteropServices; using System.Threading; class BetterScanner { ///  /// The BLUETOOTH_FIND_RADIO_PARAMS structure facilitates enumerating installed Bluetooth radios. ///  [StructLayout(LayoutKind.Sequential)] private struct BLUETOOTH_FIND_RADIO_PARAM { internal UInt32 dwSize; internal void Initialize() { this.dwSize = (UInt32)Marshal.SizeOf(typeof(BLUETOOTH_FIND_RADIO_PARAM)); } } ///  /// Closes an open object handle. ///  /// [In] A valid handle to an open object. /// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError. [DllImport("Kernel32.dll", SetLastError = true)] static extern bool CloseHandle(IntPtr handle); ///  /// Finds the first bluetooth radio present in device manager ///  /// Pointer to a BLUETOOTH_FIND_RADIO_PARAMS structure /// Pointer to where the first enumerated radio handle will be returned. When no longer needed, this handle must be closed via CloseHandle. /// In addition to the handle indicated by phRadio, calling this function will also create a HBLUETOOTH_RADIO_FIND handle for use with the BluetoothFindNextRadio function. /// When this handle is no longer needed, it must be closed via the BluetoothFindRadioClose. /// Returns NULL upon failure. Call the GetLastError function for more information on the error. The following table describe common errors: [DllImport("irprops.cpl", SetLastError = true)] static extern IntPtr BluetoothFindFirstRadio(ref BLUETOOTH_FIND_RADIO_PARAM pbtfrp, out IntPtr phRadio); [StructLayout(LayoutKind.Sequential)] private struct LE_SCAN_REQUEST { internal int scanType; internal ushort scanInterval; internal ushort scanWindow; } [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)] static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, ref LE_SCAN_REQUEST lpInBuffer, uint nInBufferSize, IntPtr lpOutBuffer, uint nOutBufferSize, out uint lpBytesReturned, IntPtr lpOverlapped); ///  /// Starts scanning for LE devices. /// Example: BetterScanner.StartScanner(0, 29, 29) ///  /// 0 = Passive, 1 = Active /// Interval in 0.625 ms units /// Window in 0.625 ms units public static void StartScanner(int scanType, ushort scanInterval, ushort scanWindow) { var thread = new Thread(() => { BLUETOOTH_FIND_RADIO_PARAM param = new BLUETOOTH_FIND_RADIO_PARAM(); param.Initialize(); IntPtr handle; BluetoothFindFirstRadio(ref param, out handle); uint outsize; LE_SCAN_REQUEST req = new LE_SCAN_REQUEST { scanType = scanType, scanInterval = scanInterval, scanWindow = scanWindow }; DeviceIoControl(handle, 0x41118c, ref req, 8, IntPtr.Zero, 0, out outsize, IntPtr.Zero); }); thread.Start(); } } 

可能如果你设置SignalStrengthFilter的 SamplingInterval频率会被改变。 试试这个:

 BluetoothLEAdvertisementWatcher watcher=new BluetoothLEAdvertisementWatcher(); watcher.SignalStrengthFilter.SamplingInterval = 100; 

对于Windows Universal App,请尝试按以下方式更改StartScanner:

 public static void StartScanner(int scanType, ushort scanInterval, ushort scanWindow) { Action action = (object obj) => { BLUETOOTH_FIND_RADIO_PARAM param = new BLUETOOTH_FIND_RADIO_PARAM(); param.Initialize(); IntPtr handle; BluetoothFindFirstRadio(ref param, out handle); uint outsize; LE_SCAN_REQUEST req = new LE_SCAN_REQUEST { scanType = scanType, scanInterval = scanInterval, scanWindow = scanWindow }; DeviceIoControl(handle, 0x41118c, ref req, 8, IntPtr.Zero, 0, out outsize, IntPtr.Zero); }; Task task = new Task(action,"nothing"); task.Start(); }