You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Android Bluetooth LE API扫描BLE设备时,如何获取信标传输的URL?

解决Android BLE扫描中提取信标URL的问题

我来帮你搞定这个问题!你现在用onLeScan回调拿扫描结果,但不知道怎么提取信标的URL,其实核心是解析广播数据里的Eddystone-URL格式(这是当前最通用的信标URL传输标准),下面分原生API和第三方库两种方案给你讲:


一、原生Android Bluetooth LE API方案(优先推荐)

onLeScan里的scanRecord字节数组包含了蓝牙广播的全部数据,我们要从中筛选出Eddystone信标的服务数据(UUID为0xFEAA),再解码出URL。

1. 解析扫描记录,定位Eddystone-URL数据

先遍历扫描记录,找到对应Eddystone服务UUID的片段:

private String parseEddystoneUrl(byte[] scanRecord) {
    int offset = 0;
    while (offset < scanRecord.length) {
        int dataLength = scanRecord[offset] & 0xFF;
        if (dataLength == 0) break;
        offset++;
        
        int dataType = scanRecord[offset] & 0xFF;
        // 筛选"服务数据"类型的广播片段
        if (dataType == 0x16) {
            // 解析服务UUID(小端序转大端)
            int serviceUuid = ((scanRecord[offset+1] & 0xFF) << 8) | (scanRecord[offset+2] & 0xFF);
            // 匹配Eddystone的服务UUID:0xFEAA
            if (serviceUuid == 0xFEAA) {
                byte frameType = scanRecord[offset+3];
                // 确认是URL类型的帧(Frame Type=0x10)
                if (frameType == 0x10) {
                    // URL数据从offset+5开始,长度为dataLength-4(减去UUID2字节+帧类型1字节+发射功率1字节)
                    return decodeCompressedUrl(scanRecord, offset + 5, dataLength - 4);
                }
            }
        }
        offset += dataLength;
    }
    return null;
}

2. 解码压缩后的URL

Eddystone-URL用了一套字符映射表压缩URL,我们需要把编码字节转成真实URL:

private String decodeCompressedUrl(byte[] scanRecord, int startOffset, int length) {
    // URL前缀映射表
    String[] urlPrefixes = {
        "http://www.",
        "https://www.",
        "http://",
        "https://"
    };
    // 特殊字符替换表
    char[] specialChars = {
        '.', '/', ':', '-', '_', '~', '%', '+',
        '@', '$', ',', '!', '\'', '(', ')', '*',
        '&', '#', ';', '=', '?', '[', ']', '^',
        ' ', '\'', '"', '\\', '|', '<', '>', '`'
    };

    StringBuilder urlBuilder = new StringBuilder();
    // 先处理URL前缀
    int prefixIndex = scanRecord[startOffset] & 0xFF;
    if (prefixIndex < urlPrefixes.length) {
        urlBuilder.append(urlPrefixes[prefixIndex]);
    }
    startOffset++;
    length--;

    // 处理剩余字符
    for (int i = 0; i < length; i++) {
        byte code = scanRecord[startOffset + i];
        int charCode = code & 0xFF;
        if (charCode <= 0x1F) {
            // 匹配特殊字符替换表
            if (charCode < specialChars.length) {
                urlBuilder.append(specialChars[charCode]);
            }
        } else if (charCode >= 0x20 && charCode <= 0x7E) {
            // 直接转ASCII可打印字符
            urlBuilder.append((char) charCode);
        }
    }
    return urlBuilder.toString();
}

3. 在onLeScan中调用解析

@Override
public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
    String beaconUrl = parseEddystoneUrl(scanRecord);
    if (beaconUrl != null) {
        // 成功拿到URL,这里做你需要的处理
        Log.d("BeaconURL", "找到URL信标: " + beaconUrl + ",RSSI: " + rssi);
    }
}

注:如果你的信标是厂商自定义的URL格式,需要对应厂商的解析规则,但Eddystone-URL是行业通用标准,绝大多数场景适用。


二、第三方库方案(简化开发)

如果觉得原生解析太繁琐,可以用成熟的信标库AltBeacon,它支持一键解析Eddystone-URL、iBeacon等多种格式:

1. 添加依赖

在app/build.gradle中加入:

dependencies {
    implementation 'org.altbeacon:android-beacon-library:2.21.4'
}

2. 初始化并扫描

// 初始化BeaconManager
BeaconManager beaconManager = BeaconManager.getInstanceForApplication(getApplicationContext());
// 配置支持Eddystone-URL格式
beaconManager.getBeaconParsers().add(new BeaconParser()
        .setBeaconLayout("s:0-1=feaa,m:2-2=10,p:3-3:-41,i:4-21v"));

// 设置距离扫描回调(实时获取信标数据)
beaconManager.addRangeNotifier((beacons, region) -> {
    for (Beacon beacon : beacons) {
        // 直接提取URL
        String url = beacon.getId1().toString();
        Log.d("BeaconURL", "第三方库解析到URL: " + url);
    }
});

// 启动扫描
try {
    beaconManager.startRangingBeaconsInRegion(new Region("myScanRegion", null, null, null));
} catch (RemoteException e) {
    e.printStackTrace();
}

额外提示

  • Android 5.0及以上更推荐用BluetoothLeScanner+ScanCallback的新API,比onLeScan更灵活,还支持扫描过滤规则。
  • 务必申请必要权限:Android 12+需要BLUETOOTH_SCAN、BLUETOOTH_CONNECT,以及位置权限(ACCESS_FINE_LOCATION/ACCESS_COARSE_LOCATION),否则BLE扫描会失效。

内容的提问来源于stack exchange,提问作者Yousha Arif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:02:43