Android 使用AltBeacon格式在发布广告时添加自定义数据

Android 使用AltBeacon格式在发布广告时添加自定义数据,android,bluetooth-lowenergy,beacon,altbeacon,Android,Bluetooth Lowenergy,Beacon,Altbeacon,我在学习Android应用程序开发的同时,正在构建一个与物理网络交互的应用程序。我想根据AltBeacon规范发布广告,并以字符串或字节的形式添加小负载。我见过Javadoc,但它写得不好。我应该使用上面javadoc中的哪个函数,或者还有其他可用的函数吗 我的目标是使用我的应用程序做广告,并传输某些字符串。如果另一个设备有我的应用程序,那么它应该显示带有该字符串的通知。我的所有代码都取自。标准蓝牙信标布局(iBeacon、AltBeacon、Eddystone UID)旨在传输唯一的数字标识符

我在学习Android应用程序开发的同时,正在构建一个与物理网络交互的应用程序。我想根据AltBeacon规范发布广告,并以字符串字节的形式添加小负载。我见过Javadoc,但它写得不好。我应该使用上面javadoc中的哪个函数,或者还有其他可用的函数吗


我的目标是使用我的应用程序做广告,并传输某些字符串。如果另一个设备有我的应用程序,那么它应该显示带有该字符串的通知。我的所有代码都取自。

标准蓝牙信标布局(iBeacon、AltBeacon、Eddystone UID)旨在传输唯一的数字标识符,而不是字符串。(Eddystone URL有点例外,因为它设计用于传输编码的URL字符串。)

然而,传输信标传输中编码的字符串肯定是可能的。请理解,这有几个限制:

  • 空间有限。信标传输中只有大约20字节的可用空间,如果使用类似ASCII的编码,可用空间为20个字符,如果使用UTF-8,可用空间可能更少,具体取决于字符

  • 您需要一定数量的匹配字节来确定(以某种合理的确定性)广告是否是“您的”,是否应该被解码为字符串。使用两个字节的匹配值会使您有1/65536的机会意外地将其他人的信标解码为字符串

  • 如果您想在iOS上接收和解码,就不能真正使用iBeacon,因为必须使用16字节的UUID进行匹配,剩下两个字节来保存字符串

  • 下面是一个示例,说明了如何使用修改后的AltBeacon布局来实现这一点,第一个两字节的匹配标识符0x8b9c用于确保它是您的信标,第二个18字节的标识符用于存储编码字符串。显示传输最大长度为18个字符的ASCII字符串的代码段:

    public static final Identifier MY_MATCHING_IDENTIFIER = Identifier.fromInt(0x8b9c);
    ...
    mBeaconManager.getBeaconParsers().clear();
    BeaconParser customBeaconParser = new BeaconParser().setBeaconLayout("m:2-3=beac,i:4-5,i:6-23,p:24-24,d:25-25");
    mBeaconManager.addBeaconParser(customBeaconParser);
    String stringToTransmit = "Only 18 chars fit!";
    byte[] stringToTransmitAsAsciiBytes = stringToTransmit.getBytes(StandardCharsets.US_ASCII);
    Beacon beacon = new Beacon.Builder().setId1(MY_MATCHING_IDENTIFIER.toString())
                .setId2(Identifier.fromBytes(stringToTransmitAsAsciiBytes, 0, 18, false).toString())
                .setTxPower(-59).build();
    mBeaconTransmitter = new BeaconTransmitter(this, customBeaconParser);
    mBeaconTransmitter.startAdvertising(beacon);
    
    这是我们收到的:

    @Override
    public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
        for (Beacon beacon : beacons) {
            if (beacon.getId1().equals(MY_MATCHING_IDENTIFIER)) {
                byte[] bytes = beacon.getId2().toByteArray();
                String receivedString = null;
                try {
                    receivedString = new String(bytes, 0, bytes.length, "ASCII");
                } catch (UnsupportedEncodingException e) {
                    Log.d(TAG, "Cannot decode ASII");
                }
                Log.d(TAG, "I just received: "+receivedString);
            }
        }
    }
    
    @覆盖
    公共无效范围信标区域(收集信标,区域){
    用于(信标:信标){
    if(beacon.getId1().equals(我的匹配标识符)){
    字节[]字节=beacon.getId2().toByteArray();
    字符串receivedString=null;
    试一试{
    receivedString=新字符串(字节,0,bytes.length,“ASCII”);
    }捕获(不支持的编码异常e){
    Log.d(标记“无法解码ASII”);
    }
    Log.d(标记“我刚刚收到:”+receivedString);
    }
    }
    }
    

    编辑:确保如上所示清除信标解析器,否则代码将尝试使用默认信标解析器。请参阅上面的代码更改。

    因此,如果我使用MD5哈希,而不是32个字符,我管理16个字符,那么我可以更准确地实现这一点,同时为我提供两个额外的字节作为唯一的初始字节。使获得重复匹配更加困难。那么概率将是256^4中的1。它是correct@davidyoungBeaconManager中没有clearBeaconParsers方法。请检查文档对不起,使用:
    mBeaconManager.getBeaconParsers().clear()我一直在使用一个实验性的V3API,它使用了前面显示的新语法。我已经更新了我的答案。有人可能会发现这个有用的setDataFields,setExtraDataFields可能看起来可以容纳额外的负载,但它们只能保持6字节的负载或Java的长度。