首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何识别Eddystone URL和uid?

如何识别Eddystone URL和uid?
EN

Stack Overflow用户
提问于 2015-09-29 06:03:11
回答 3查看 5.3K关注 0票数 3

我希望检测Eddystone Ul和uid,而不使用邻近信标API或附近的Messages。我希望使用本地的安卓库,如BluetoothAdapter、BluetoothGatt或BluetoothGap来解析eddystone框架。这可行吗?如果是这样,怎么做,如果不可行,那还有什么可供选择的?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-09-30 16:59:23

下面是--获取Eddystone AFAIK信息的最简单方法。

代码语言:javascript
复制
// onLeScan() method of BluetoothAdapter.LeScanCallback interface.
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)
{
    // Parse the payload of the advertisement packet
    // as a list of AD structures.
    List<ADStructure> structures =
        ADPayloadParser.getInstance().parse(scanRecord);

    // For each AD structure contained in the advertisement packet.
    for (ADStructure structure : structures)
    {
        // If the AD structure represents Eddystone UID.
        if (structure instanceof EddystoneUID)
        {
            // Eddystone UID
            EddystoneUID es = (EddystoneUID)structure;

            Log.d(TAG, "Tx Power = "     + es.getTxPower());
            Log.d(TAG, "Namespace ID = " + es.getNamespaceIdAsString());
            Log.d(TAG, "Instance ID = "  + es.getInstanceIdAsString());
            Log.d(TAG, "Beacon ID = "    + es.getBeaconIdAsString());

            // As byte arrays if you want.
            byte[] namespaceId = es.getNamespaceId();
            byte[] instanceId  = es.getInstanceId();
            byte[] beaconId    = es.getBeaconId();
        }
        // If the AD structure represents Eddystone URL.
        else if (structure instanceof EddystoneURL)
        {
            // Eddystone URL
            EddystoneURL es = (EddystoneURL)structure;

            Log.d(TAG, "Tx Power = " + es.getTxPower());
            Log.d(TAG, "URL = "      + es.getURL());
        }
        // If the AD structure represents Eddystone TLM.
        else if (structure instanceof EddystoneTLM)
        {
            // Eddystone TLM
            EddystoneTLM es = (EddystoneTLM)structure;

            Log.d(TAG, "TLM Version = "         + es.getTLMVersion());
            Log.d(TAG, "Battery Voltage = "     + es.getBatteryVoltage());
            Log.d(TAG, "Beacon Temperature = "  + es.getBeaconTemperature());
            Log.d(TAG, "Advertisement Count = " + es.getAdvertisementCount());
            Log.d(TAG, "Elapsed Time = "        + es.getElapsedTime());
        }
    }
}

如果使用Eddystone规范,则不必了解有关nv-蓝牙的详细信息。

Gradle

代码语言:javascript
复制
dependencies {
    compile 'com.neovisionaries:nv-bluetooth:1.7'
}

JavaDoc

JavaDoc

备忘

Eddystone TLM中的信标温度用符号不动点表示法表示.在编写本文时,如何检测与Eddystone兼容的信标 (Android )中的代码示例没有显示如何将数据提取为浮点数。另一方面,nv-蓝牙中的EddystoneTLM类有如下所示的方法,所以您不必对定点符号进行解码。

代码语言:javascript
复制
public float getBeaconTemperature();

同样,EddystoneURL类有一个方法将URL作为URL来获取。

代码语言:javascript
复制
public URL getURL();

因此,当您使用时,您不需要执行下面这样的步骤。

代码语言:javascript
复制
String url = UrlBeaconUrlCompressor.uncompress(beacon.getId1().toByteArray());

蓝牙将与Eddystone相关的数据结构作为继承树实现,如下所示。这种适当的继承树在其他库中很难找到。

代码语言:javascript
复制
ADStructure
  |
  +-- ServiceData
        |
        +-- Eddystone
              |
              +-- EddystoneUID
              |
              +-- EddystoneURL
              |
              +-- EddystoneTLM

正确继承树的好处之一是将方法放置在正确的位置。如下所示:

代码语言:javascript
复制
ADStructure
  |  // AD Structure Length - 1
  |  int getLength();
  |
  |  // AD Type
  |  int getType();
  |
  |  // AD Data
  |  byte[] getData();
  |
  +-- ServiceData
  |     |  // Service UUID
  |     |  UUID getServiceUUID();
  |     |
  |     +-- Eddystone
  |           |  // Eddystone Frame Type
  |           |  FrameType getFrameType();
  |           |
  |           +-- EddystoneUID
  |           |     // Tx Power
  |           |     int getTxPower();
  |           |
  |           |     // Namespace ID (byte[])
  |           |     byte[] getNamespaceId();
  |           |
  |           |     // Instance ID (byte[])
  |           |     byte[] getInstanceId();
  |           |
  |           |     // Beacon ID (byte[])
  |           |     byte[] getBeaconId();
  |           |
  |           |     // Namespace ID (String)
  |           |     String getNamespaceIdAsString();
  |           |
  |           |     // Instance ID (String)
  |           |     String getInstanceIdAsString();
  |           |
  |           |     // Beacon ID (String)
  |           |     String getBeaconIdAsString();
  |           |
  |           +-- EddystoneURL
  |           |     // Tx Power
  |           |     int getTxPower();
  |           |
  |           |     // URL
  |           |     URL getURL();
  |           |
  |           +-- EddystoneTLM
  |                 // TLM Version
  |                 int getTLMVersion();
  |
  |                 // Battery Voltage
  |                 int getBatteryVoltage();
  |
  |                 // Beacon Temperature
  |                 float getBeaconTemperature();
  |
  |                 // Advertisement Count
  |                 long getAdvertisementCount();
  |
  |                 // Elapsed Time
  |                 long getElapsedTime();
  |
  +-- ADManufacturerSpecific
  |      |  // Company ID
  |      |  int getCompanyId();
  |      |
  |      +-- IBeacon
  |      |     // Major Number
  |      |     int getMajor();
  |      |
  |      |     (abbrev)
  |      |
  |      +-- Ucode
  |      |     // Ucode
  |      |     String getUcode();
  |      |
  |      |     (abbrev)
票数 4
EN

Stack Overflow用户

发布于 2015-09-29 08:10:40

所有Eddystone数据都包含在蓝牙4.0 (“低能”、"BLE")广告包中,因此不需要BluetoothGattBluetoothGap。使用BluetoothLeScanner代替。在onScanResult回调中,您可以通过以下方式访问广告数据:

代码语言:javascript
复制
// assuming `result` is the ScanResult passed to the `onScanResult` callback
byte[] rawData = result
    .getScanRecord()
    .getServiceData(ParcelUuid.fromString("0000FEAA-0000-1000-8000-00805F9B34FB"));

然后,您需要根据Eddystone规范解析字节:

UID: https://github.com/google/eddystone/tree/master/eddystone-uid

URL: https://github.com/google/eddystone/tree/master/eddystone-url

Eddystone回购中还包含了一个示例项目,因此您可能可以从那里开始,也许可以重用一些代码:

https://github.com/google/eddystone/tree/master/tools/eddystone-validator

票数 4
EN

Stack Overflow用户

发布于 2015-09-29 12:46:36

您可以使用本地的Android onLeScan回调来检测Eddystone-UID信标。我已经在下面的答案中发布了示例代码,展示了如何做到这一点:

https://stackoverflow.com/a/32799901/1461050

代码语言:javascript
复制
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
    for (int startByte = 0; startByte < scanRecord.length; startByte++) {
        if (scanRecord.length-startByte > 19) { // need at least 19 bytes for Eddystone-UID
            // Check that this has the right pattern needed for this to be Eddystone-UID
            if (scanRecord[startByte+0] == 0xaa && scanRecord[startByte+1] == 0xfe &&
                    scanRecord[startByte+2] == 0x00) {
                // This is an Eddystone-UID beacon.
                byte[] namespaceIdentifierBytes = Arrays.copyOfRange(scanRecord, startByte+4, startByte+13);
                byte[] instanceIdentifierBytes = Arrays.copyOfRange(scanRecord, startByte+14, startByte+19);
                // TODO: do something with the above identifiers here
            }
        }

    }
}

这样做的关键是理解和解析每种信标类型的字节布局。这就是开源Android灯塔图书馆如何通过为每个信标定义布局表达式来解析多个信标类型,以帮助解析。即使您想要滚动您自己的代码,您也可以查看它的源代码并使用它来了解它是如何工作的。我已经在上面链接的答案中发布了关于这个解析是如何发生的描述。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32836728

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档