Service UUID:是什么、格式及应用场景

作者: IT Sectr 发布日期: 2026-07-14 阅读时间: 8 分钟

Service UUID — 是一个唯一的16位或128位蓝牙低功耗(BLE)标识符,用于明确定义设备上的功能性服务。Bluetooth SIG为常见服务分配了标准16位UUID,例如Battery Service(0x180F)、Device Information(0x180A)和Heart Rate(0x180D),这简化了跨平台兼容性。根据Bluetooth Core Specification 5.4(2023),第三方开发者的自定义服务必须使用128位UUID,其格式无需中央注册表即可保证全局唯一性。正确声明Service UUID是外设设备上GATT服务器正常工作的第一步。

要点

  • Service UUID — BLE服务标识符,可以是16位(标准)或128位(自定义)。
  • Bluetooth SIG为常见服务分配了超过60个标准UUID — Battery、Heart Rate、Device Information等。
  • 128位UUID由开发者生成,无需在中央机构注册即可保证服务的全局唯一性
  • 扫描时,Central根据其Service UUID检测Peripheral的服务,这决定了设备的兼容性。
  • 一个GATT服务器可以声明多个服务,每个服务具有不同的UUID — 每个服务包含自己的特征。

BLE中的Service UUID是什么?

Service UUID — 是分配给蓝牙低功耗GATT服务以使其能够被其他设备唯一识别的标识符。在BLE架构中,每个服务代表一组由共同功能连接起来的逻辑特征组。例如,Battery Service服务包含Battery Level特征,用于传输当前电池电量水平。

Bluetooth SIG(特别兴趣小组)管理分配给最常见服务的标准16位UUID注册表。这使得不同制造商的设备无需预先配置即可相互识别服务。任何品牌的健身追踪器都可以声明UUID为0x180D的Heart Rate Service,任何智能手机都会理解这是心率服务。

根据Bluetooth Core Specification 5.4(2023),16位UUID范围(0x0000–0xFFFF)分为两部分:0x0001至0xFFFE — Bluetooth SIG标准服务,0xFFFF为保留。如果开发者需要SIG注册表中不存在的唯一服务,则使用128位UUID。

标准UUID和自定义UUID之间的区别不仅在于长度:16位UUID节省广播包的无线时间,因为它们以2字节而非16字节传输。对于广播包大小有严格限制(最多31字节)的设备来说,这一点至关重要。

标准和自定义UUID

标准16位UUID涵盖BLE设备的主要类别:医疗传感器、健身追踪器、可穿戴电子设备和配件。如果设备实现标准功能 — 建议开发者使用Bluetooth SIG注册表中相应的UUID以获得最大兼容性。

以下是一些标准服务UUID的示例:

UUID(十六进制)服务名称用途
0x1800Generic Access访问管理、设备名称、外观
0x180ADevice Information制造商、型号、序列号、软件版本
0x180DHeart Rate脉搏测量、传感器位置、电池电量
0x180FBattery Service电池电量百分比
0x181AEnvironmental Sensing温度、湿度、压力、光照
0x181CUser Data年龄、体重、身高、性别、静息脉搏

自定义128位UUID在设备提供独特功能时是必需的。例如,智能锁制造商创建自己的Lock Control服务,UUID格式为XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX。这样的UUID保证不会与其他服务冲突,因为128位值的空间几乎是无穷无尽的。

128位UUID的格式

128位UUID以标准UUID RFC 4122格式编写:八个十六进制字符,连字符,四个,连字符,四个,连字符,四个,连字符,十二个字符。BLE使用的版本中,Bluetooth SIG UUID的基础部分具有固定位。

Bluetooth SIG定义了基础UUID:0000XXXX-0000-1000-8000-00805F9B34FB。对于标准16位服务,UUID值将替换到此掩码中:例如,0x180F变为0000180F-0000-1000-8000-00805F9B34FB。自定义服务使用完全独立的由开发者生成的UUID。

创建自定义UUID时,可以使用任何UUID生成器(UUID v4)。随机UUID v4提供122位熵,使得冲突几乎不可能。不要使用修改后的Bluetooth SIG基础UUID版本用于自定义服务 — 这违反了规范。

如何在代码中声明带UUID的服务

声明服务带UUID是在创建GATT服务器时在Peripheral端执行的。在iOS中使用Core Bluetooth,在Android中使用android.bluetooth.le。让我们来讨论这两种方法。

iOS:Core Bluetooth

Swift中,通过CBMutableService指定UUID创建服务,然后通过CBMutableCharacteristic向其添加特征。

swift
import CoreBluetooth

// 标准16位UUID
let batteryServiceUUID = CBUUID("180F")

// 自定义128位UUID
let customServiceUUID = CBUUID("E20A39F4-73F5-4BC4-A12F-17D1AD07A961")

let service = CBMutableService(
    type: customServiceUUID,
    primary: true
)

// 添加特征
service.characteristics = [characteristic]

// 通过peripheralManager发布服务
peripheralManager.add(service)

Android:Bluetooth GATT Server

Android中,通过BluetoothGattServer和BluetoothGattService注册服务。UUID作为字符串在java.util.UUID.fromString中传递。

java
import android.bluetooth.*;

// 自定义服务UUID
private static final UUID CUSTOM_SERVICE_UUID =
    UUID.fromString("E20A39F4-73F5-4BC4-A12F-17D1AD07A961");

BluetoothGattService service = new BluetoothGattService(
    CUSTOM_SERVICE_UUID,
    BluetoothGattService.SERVICE_TYPE_PRIMARY
);

// 添加特征
service.addCharacteristic(characteristic);

// 在GATT服务器上注册
gattServer.addService(service);

按UUID扫描服务

按Service UUID扫描允许Central查找提供所需服务的设备,而无需连接到所有检测到的Peripheral。BLE广播包可以包含服务UUID列表,这使得Central能够在扫描阶段过滤设备。

iOS中,CBCentralManager使用按服务UUID的过滤器扫描设备。这降低了功耗并加快了所需设备的检测速度。

swift
import CoreBluetooth

let centralManager = CBCentralManager()

func scanForHeartRateMonitor() {
    let services: [CBUUID] = [
        CBUUID("180D") // Heart Rate Service
    ]
    centralManager.scanForPeripherals(
        withServices: services,
        options: nil
    )
}

// 委托仅接收Heart Rate Service设备
func centralManager(
    _ central: CBCentralManager,
    didDiscover peripheral: CBPeripheral,
    advertisementData: [String: Any],
    rssi RSSI: NSNumber
) {
    // peripheral仅具有UUID 0x180D的设备
}

Android中,按UUID过滤也通过ScanFilter.Builder支持。这是一种无需连接到每个设备即可缩小搜索范围的有效方法。

java
import android.bluetooth.le.*;

ScanFilter filter = new ScanFilter.Builder()
    .setServiceUuid(
        new ParcelUuid(
            UUID.fromString("0000180D-0000-1000-8000-00805F9B34FB")
        )
    )
    .build();

BluetoothLeScanner scanner = bluetoothAdapter.getBluetoothLeScanner();
scanner.startScan(
    Collections.singletonList(filter),
    scanSettings,
    scanCallback
);

单个设备上的多个服务

一个BLE设备可以同时声明多个服务。例如,健身手环可以包含Battery Service(0x180F)、Heart Rate Service(0x180D)和用于与云端数据同步的自定义服务。每个服务都有自己的UUID和自己的一组特征。

在有多个服务的情况下,重要的是要考虑广播包的限制。BLE广播包最多可以包含31字节的数据。如果服务UUID占用太多空间,其中一些可能无法放入广播包。在这种情况下,使用扫描响应(scan response)— 根据Central的请求发送的第二个数据包。

根据Bluetooth Core Specification 5.4(2023),单个GATT服务器上主要服务的最大数量不受规范限制,但实际上受设备内存和性能要求的限制。对于具有256 KB闪存的嵌入式设备,建议不超过5到10个服务。

常见问题

16位UUID和128位UUID有什么区别?

16位UUID由Bluetooth SIG为标准服务保留,在广播包中占用2字节。128位UUID用于自定义服务,占用16字节。选择取决于服务类型:标准功能使用16位UUID,独特功能使用128位UUID。

如何为BLE服务生成自定义128位UUID?

使用UUID v4 — 由在线工具、终端命令uuidgen或您的编程语言API生成的随机UUID。示例:Java中的UUID.fromString(UUID.randomUUID().toString())或Swift中的UUID()。

是否需要在Bluetooth SIG中注册自定义UUID?

不需要,注册不是必须的。Bluetooth SIG仅注册16位UUID。自定义128位UUID由开发者独立生成,并凭借巨大的地址空间(2^128种组合)保证唯一性。

一个服务可以包含多个特征吗?

是的,标准GATT服务可以包含无限数量的特征。例如,Battery Service可以包含Battery Level(0x2A19)和Battery Power State(0x2A1A)。每个特征都有自己的UUID和属性集。

如果两个设备使用相同的自定义UUID会发生什么?

如果UUID匹配,Central将无法在没有额外信息的情况下区分一个服务和另一个服务。随机UUID v4冲突的概率微乎其微 — 约为5.3 × 10^−37。请使用随机UUID生成器,不要复制示例中的UUID。

总结

  • Service UUID — BLE服务的全局标识符,可以是16位(标准)或128位(自定义)。
  • Bluetooth SIG分配了超过60个标准UUID — 使用它们与其他制造商的设备兼容。
  • 128位UUID由开发者通过UUID v4创建,无需中央注册即可保证唯一性。
  • 扫描时,Central根据Service UUID过滤设备,从而降低功耗并加快搜索速度。
  • 单个设备可以声明多个服务,具有不同的UUID — 数量受内存和广播包限制。
  • iOS和Android中,分别通过CBMutableService和BluetoothGattService指定UUID来声明服务。
  • 正确选择UUID会影响兼容性、广播包大小以及GATT配置文件的正确运行。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读