蓝牙 LE 播发

本主题概述了 通用 Windows 平台 (UWP) 应用的蓝牙低功耗 (LE) 播发信标。

重要

必须在 Package.appxmanifest 中声明“蓝牙”功能才能使用此功能。

<Capabilities> <DeviceCapability Name="bluetooth" /> </Capabilities>

重要的 API

受支持的功能

LE 播发 API 支持两大功能:

  • 播发观察程序:侦听是否存在附近的信标,并根据有效负载或邻近度将其筛选出来。
  • 播发发布程序:定义 Windows 有效负载,以代表开发人员进行播发。

示例

有关蓝牙 LE 播发的完整功能示例,请参阅 GitHub 上的蓝牙播发示例

基本设置

若要在通用 Windows 平台应用中使用基本蓝牙 LE 功能,则须在 Package.appxmanifest 中检查蓝牙功能。

  1. 打开 Package.appxmanifest
  2. 转到“功能”选项卡
  3. 在左侧列表中查找“蓝牙”,然后选中它旁边的框。

发布播发

蓝牙 LE 播发允许设备不断标出特定有效负载(称为一次播发)。 如果已设置支持 LE 的任意附近蓝牙设备以侦听是否存在此特定播发,则此类设备均可发现此播发。

注意

为保护用户隐私,播发的生命周期与应用的生命周期相关。 可创建 BluetoothLEAdvertisementPublisher,并在后台任务中调用 Start 以进行播发。 有关后台任务的详细信息,请参阅启动、恢复和后台任务

可通过多种方式将数据添加到播发。 此示例演示了创建特定于公司的播发的常见方法。

首先,创建播发发布程序,它可控制设备是否正在标出特定播发。

BluetoothLEAdvertisementPublisher publisher = new BluetoothLEAdvertisementPublisher();

然后,创建自定义数据部分。 此示例使用未分配的 CompanyId0xFFFE 并将文本 Hello World 添加到播发中。

// Add custom data to the advertisement
var manufacturerData = new BluetoothLEManufacturerData();
manufacturerData.CompanyId = 0xFFFE;

var writer = new DataWriter();
writer.WriteString("Hello World");

// Make sure that the buffer length can fit within an advertisement payload (~20 bytes). 
// Otherwise you will get an exception.
manufacturerData.Data = writer.DetachBuffer();

// Add the manufacturer data to the advertisement publisher:
publisher.Advertisement.ManufacturerData.Add(manufacturerData);

现在,已创建和设置了发布者,你可以调用“开始”来开始发布广告

publisher.Start();

监视是否存在播发

以下代码演示如何创建蓝牙 LE 播发观察程序、设置回调并开始监视是否存在 LE 播发。

BluetoothLEAdvertisementWatcher watcher = new BluetoothLEAdvertisementWatcher();
watcher.Received += OnAdvertisementReceived;
watcher.Start();
private async void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
    // Do whatever you want with the advertisement
}

主动扫描

若要同时接收扫描响应播发,则应在创建观察程序后设置以下内容。 请注意,此操作将导致更大的耗用功率,且在后台模式下不可用。

watcher.ScanningMode = BluetoothLEScanningMode.Active;

监视是否存在特定播发模式

有时,你想侦听是否存在特定播发。 在本例中,我们会侦听是否存在包含虚构公司(标识为 0xFFFE)有效负载且在播发中包含字符串 Hello World 的播发。 它可与“基本发布”示例配对,以便有一个 Windows 计算机用于播发,而另一个计算机会用于监视。 在启动观察程序之前,请务必设置此播发筛选器!

var manufacturerData = new BluetoothLEManufacturerData();
manufacturerData.CompanyId = 0xFFFE;

// Make sure that the buffer length can fit within an advertisement payload (~20 bytes). 
// Otherwise you will get an exception.
var writer = new DataWriter();
writer.WriteString("Hello World");
manufacturerData.Data = writer.DetachBuffer();

watcher.AdvertisementFilter.Advertisement.ManufacturerData.Add(manufacturerData);

监视是否存在附近的播发

有时,仅当设备播发已进入范围时,你才想触发观察程序。 可定义自己的范围,但需注意值会剪切为 0 到 -128 之间。

// Set the in-range threshold to -70dBm. This means advertisements with RSSI >= -70dBm 
// will start to be considered "in-range" (callbacks will start in this range).
watcher.SignalStrengthFilter.InRangeThresholdInDBm = -70;

// Set the out-of-range threshold to -75dBm (give some buffer). Used in conjunction 
// with OutOfRangeTimeout to determine when an advertisement is no longer 
// considered "in-range".
watcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = -75;

// Set the out-of-range timeout to be 2 seconds. Used in conjunction with 
// OutOfRangeThresholdInDBm to determine when an advertisement is no longer 
// considered "in-range"
watcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(2000);

测量距离

触发蓝牙 LE 观察程序的回调时,eventArgs 将包含一个 RSSI 值,从而告知接收到的信号强度(蓝牙信号的强度)。

private async void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
   // The received signal strength indicator (RSSI)
   Int16 rssi = eventArgs.RawSignalStrengthInDBm;
}

该值可大致转换为距离,但不应用于测量真实距离,因为每条无线电均各不相同。 不同的环境因素可能会使距离难以测量(如墙壁、无线电周围的情况,甚至还有空气湿度)。

判断纯距离的替代方法是定义“存储桶”。 无线电往往会在非常接近时报告 0 到 -50 DBm,处于中距离时报告 -50 到 -90 DBm,距离很远时则报告 -90 DBm 以下。 试错法最适合用于确定适用于你的应用的存储桶。