gpt4 book ai didi

android - 如何通过 scanRecord 识别 Eddystone

转载 作者:太空宇宙 更新时间:2023-11-03 12:50:19 25 4
gpt4 key购买 nike

我正在开发一款扫描 BLE 设备的 Android 应用程序。每次找到设备时,我都会收到: byte[] scanRecord, BluetoothDevice 设备, int rssi 来自 BluetoothAdapter.startLeScan()

然后我将字节数组转换为 ScanRecord 对象: ScanRecord.parseFromBytes()

我现在从我的 Eddystone 中获得了以下信息(来自 toString() 方法)。

`com.reelyactive.blesdk.support.ble.ScanRecord [mAdvertiseFlags=6, mServiceUuids=[0000feaa-0000-1000-8000-00805f9b34fb], mManufacturerSpecificData={}, mServiceData={0000feaa-0000-1000-8000-00805f9b34fb=[16, -36, 2, 107, 110, 116, 107, 46, 105, 111, 47, 101, 100, 100, 121, 115, 116, 111, 110, 101], 0000d00d-0000-1000-8000-00805f9b34fb=[67, 77, 103, 52, 50, 57, 100]}, mTxPowerLevel=-12, mDeviceName=IIS_EDDY_003] IIS_EDDY_003` 

谁能告诉我,如何使用这些信息将设备识别为 Eddystone?服务uuid​​可能吗?我并不总是知道设备的名称或地址。

最佳答案

android.bluetooth.le.ScanRecord 是 Android 中最糟糕的 API 之一。

如果你已经有了scanRecord(字节数组),我推荐 nv-bluetooth 提取 Eddystone 数据。以下代码 fragment 显示了 nv-bluetooth 的用法。

// Parse the payload of the advertising packet.
List<ADStructure> structures =
ADPayloadParser.getInstance().parse(scanRecord);

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

// (1) Calibrated Tx power at 0 m.
int power = es.getTxPower();

// (2) 10-byte Namespace ID
byte[] namespaceId = es.getNamespaceId();
String namespaceIdAsString = es.getNamespaceIdAsString();

// (3) 6-byte Instance ID
byte[] instanceId = es.getInstanceId();
String instanceIdAsString = es.getInstanceIdAsString();

// (4) 16-byte Beacon ID
byte[] beaconId = es.getBeaconId();
String beaconIdAsString = es.getBeaconIdAsString();
}
else if (structure instanceof EddystoneURL)
{
// Eddystone URL
EddystoneURL es = (EddystoneURL)structure;

// (1) Calibrated Tx power at 0 m.
int power = es.getTxPower();

// (2) URL
URL url = es.getURL();
}
else if (structure instanceof EddystoneTLM)
{
// Eddystone TLM
EddystoneTLM es = (EddystoneTLM)structure;

// (1) TLM Version
int version = es.getTLMVersion();

// (2) Battery Voltage
int voltage = es.getBatteryVoltage();

// (3) Beacon Temperature
float temperature = es.getBeaconTemperature();

// (4) Advertisement count since power-on or reboot.
long count = es.getAdvertisementCount();

// (5) Elapsed time in milliseconds since power-on or reboot.
long elapsed = es.getElapsedTime();
}
else if (structure instanceof IBeacon)
{
// iBeacon
IBeacon iBeacon = (IBeacon)structure;

// (1) Proximity UUID
UUID uuid = iBeacon.getUUID();

// (2) Major number
int major = iBeacon.getMajor();

// (3) Minor number
int minor = iBeacon.getMinor();

// (4) Tx Power
int power = iBeacon.getPower();
}
}

上面的代码暗示扫描记录应该被解析为AD结构的列表。但是,android.bluetooth.le.ScanRecordparseFromBytes 没有以正确的方式解析扫描记录。

ScanRecord 具有以下方法(以及其他一些方法):

  1. getAdvertiseFlags()
  2. getDeviceName()
  3. getManufacturerSpecificData()
  4. getServiceData()
  5. getTxPowerLevel()

这些方法对应一些AD结构。此 API 设计与下面所示的 AnimalRecord 类结构相同。

public class AnimalRecord
{
public Cat getCat() { ... }
public Dog getDog() { ... }
public Eagle getEagle() { ... }
...
}

标志、本地名称、制造商特定数据、服务数据和 Tx 功率级别也应解析为如下所示的 AD 结构。

// Parse the payload of the advertising packet.
List<ADStructure> structures =
ADPayloadParser.getInstance().parse(scanRecord);

// For each AD structure contained in the payload.
for (ADStructure structure : structures)
{
if (structure instanceof Flags)
{
// Flags
Flags flags = (Flags)structure;
}
else if (structure instanceof LocalName)
{
// Local Name
LocalName name = (LocalName)structure;
}
else if (structure instanceof ADManufacturerSpecific)
{
// Manufacturer Specific Data
// Note that iBeacon is a kind of Manufacturer Specific Data
ADManufacturerSpecific ms = (ADManufacturerSpecific)structure;
}
else if (structure instanceof ServiceData)
{
// Service Data
// Note that Eddystone is a kind of Service Data.
ServiceData sd = (ServiceData)structure;
}
else if (structure instanceof TxPowerLevel)
{
// TxPowerLevel
TxPowerLevel level = (TxPowerLevel)structure;
}
}

正如上面代码中所注释的,Eddystone 是一种服务数据。因此,Eddystone UID、Eddystone URL 和 Eddystone TLM 应该具有如下继承树。

ADStructure
|
+-- ServiceData
|
+-- Eddystone
|
+-- EddystoneUID
+-- EddystoneURL
+-- EddystoneTLM

我希望那些非常了解BLE规范并具有良好设计能力的人能够从头开始重写Android的BLE API。

关于android - 如何通过 scanRecord 识别 Eddystone,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32735016/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com