安卓BLE社交距离接触追踪APP如何通过Bluetooth UUID实现设备标识广播与存储
设备唯一ID生成实现方案
- 先避开必踩坑:别用硬件序列号、系统MAC地址当设备标识,安卓6.0以上普通应用根本拿不到这些信息,而且这类硬件标识的使用会触发隐私合规问题,很容易导致应用过不了审。
- 最稳妥的落地逻辑:应用第一次启动时,在自己的本地私有存储里生成一个永久保留的随机全局唯一字符串当设备ID,不需要申请任何额外权限,只要用户不卸载应用,这个ID就一直稳定存在。
可直接复用的代码逻辑:// 应用启动时读取/生成本机唯一设备ID val privatePref = getSharedPreferences("app_private_config", Context.MODE_PRIVATE) var localDeviceId = privatePref.getString("unique_device_id", null) if (localDeviceId == null) { // 生成随机UUID作为永久设备ID localDeviceId = UUID.randomUUID().toString() privatePref.edit().putString("unique_device_id", localDeviceId).apply() }
BLE广播自身ID的实现方法
- 首先明确广播的硬限制:BLE广播包的最大可用空间仅31字节,根本塞不下长度36位的UUID字符串,这是新手做BLE广播最容易踩的坑,很多人写完广播逻辑跑不起来,都是因为硬塞长字符串导致广播包超限。
- 提前定义所有App统一使用的16位短服务UUID(而非通用的128位长UUID),占空间极小,能顺利塞进广播包。比如选一个没被占用的16位标识值
0xFFE0,转成标准UUID格式写死在代码里,所有装这个App的设备都认这个标识,扫描的时候直接过滤掉别的无关蓝牙设备,不用做多余的判断。 - 构造广播内容时,别开设备名称广播(会白占很多空间),把本地生成的设备ID通过广播包的服务数据字段带出去。这样别的设备扫到广播的时候,不需要和你建立复杂的BLE GATT连接,直接从收到的广播数据里就能解析出你的设备ID,对新手来说实现难度低很多,不用啃GATT连接的复杂流程。
广播配置的参考代码:
// 全局统一的App专属服务UUID val APP_SERVICE_UUID = UUID.fromString("0000FFE0-0000-1000-8000-00805F9B34FB") // 构造广播数据包 val advertiseConfig = AdvertiseData.Builder() .addServiceUuid(ParcelUuid(APP_SERVICE_UUID)) // 把本地设备ID转成字节数组,存到广播的服务数据字段里 .addServiceData(ParcelUuid(APP_SERVICE_UUID), localDeviceId.toByteArray()) .setIncludeDeviceName(false) .build() - 提前定义所有App统一使用的16位短服务UUID(而非通用的128位长UUID),占空间极小,能顺利塞进广播包。比如选一个没被占用的16位标识值
- 提前把权限配好:安卓12及以上版本需要在Manifest里申请
BLUETOOTH_ADVERTISE、BLUETOOTH_SCAN权限,安卓11及以下版本要申请位置权限才能正常扫描BLE信号,缺了这些权限功能会直接失效。
接入History板块的存储逻辑
- 当扫描模块捕获到带专属App服务UUID的广播信号时,直接从广播包的服务数据字段解析出对方的设备唯一ID。
- 你已经实现了接触时间记录、间距测量的功能,只需要在原有History的存储结构里新增一个
contacted_device_id字段,把解析出来的对方ID、已记录的接触时间、已测量的间距值,打包成一条记录写入本地存储就行,不需要改动之前写好的核心逻辑。 - 加个简单的去重逻辑:对同一台设备短时间内连续发的广播,做5-10分钟的缓存窗口,别短时间往History里重复写好几条同一个ID的记录,攒一堆无效数据。
内容的提问来源于stack exchange,提问作者Hazem Shereef
相关产品推荐
相关产品推荐

