我希望在不使用邻近信标api或附近消息api的情况下检测eddystone ul和uid。我希望使用原生android库,比如bluetoothadapter、bluetoothgatt或bluetoothgap来解析eddystone框架。这可行吗?如果是这样的话,如果不可行,那么还有什么可供选择的呢?

最佳答案

以下是获取埃迪斯通AFAIK信息的最简单方法。

// 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 specification,则不必知道有关nv-bluetooth的详细信息。
小精灵
dependencies {
    compile 'com.neovisionaries:nv-bluetooth:1.7'
}

文档注释
JavaDoc
备忘录
Eddystone TLM中的信标温度用有符号定点表示法表示。在本文撰写时,How to detect Eddystone-Compatible Beacons(android beacon library)中的代码示例没有显示如何将数据提取为浮点数。另一方面,nv bluetooth中的EddystoneTLM类有如下所示的方法,因此您不必解码定点表示法。
public float getBeaconTemperature();

同样,EddystoneURL类也有一个方法将url获取为URL
public URL getURL();

所以,当你使用android beacon库时,你不必像下面这样做。
String url = UrlBeaconUrlCompressor.uncompress(beacon.getId1().toByteArray());

nv-bluetooth以继承树的形式实现与eddystone相关的数据结构,如下所示。这种合适的继承树在其他库中很难找到。
ADStructure
  |
  +-- ServiceData
        |
        +-- Eddystone
              |
              +-- EddystoneUID
              |
              +-- EddystoneURL
              |
              +-- EddystoneTLM

正确继承树的好处之一是方法被放置在正确的位置。这样地:
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)

关于android - 如何识别Eddystone URL和uid?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32836728/

10-12 06:27