问题包括检测IBeacon和Eddystone帧,当我有Eddystone时,我必须使用特定的函数,IBeacon也是如此。我在Android中使用Java,所以传递给我IBeacon结果的函数是getManufatureSpecificData(),而Eddystone的函数是getServiceData()。问题是为什么会有不同的功能来产生结果呢?如何检查接收到的帧是Eddystone还是IBeacon?
代码片段
public void onBatchScanResults(List<ScanResult> results) {
super.onBatchScanResults(results);
beaconManager.clean();
Log.i(TAG, "On batch called, size of result is : " + results.size());
for (int index = 0; index < results.size(); ++index) {
try {
ScanRecord mScanRecord = results.get(index).getScanRecord();
Map<ParcelUuid, byte[]> myMap = mScanRecord.getServiceData();
int mRsi = results.get(index).getRssi();
String url = "";
byte[] txPower = new byte[1];
byte[] nameSpaceId = new byte[10];
byte[] instanceId = new byte[6];
float distance;
for (Map.Entry<ParcelUuid, byte[]> eddystoneFrame : myMap.entrySet()) {
// for eddystone URL
if (eddystoneFrame.getValue()[0] == 16) {
url += urlSchemePrefix[eddystoneFrame.getValue()[2]];
for (int i = 3; i < eddystoneFrame.getValue().length - 1; i++) {
url += (char) eddystoneFrame.getValue()[i];
}
url += topLevelDomain[eddystoneFrame.getValue()[eddystoneFrame.getValue().length - 1]];
txPower[0] = eddystoneFrame.getValue()[1];
distance = (float) Utils.calculateDistance((int) txPower[0], (double) mRsi);
try {
beaconManager.addEddyBeacon(Utils.bytesToHex(nameSpaceId), Utils.bytesToHex(instanceId), distance);
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
else if (eddystoneFrame.getValue()[0] == 0) {
// For Eddystone UID
System.arraycopy(eddystoneFrame.getValue(), 2, nameSpaceId, 0, nameSpaceId.length);
System.arraycopy(eddystoneFrame.getValue(), 12, instanceId, 0, instanceId.length);
System.arraycopy(eddystoneFrame.getValue(), 1, txPower, 0, txPower.length);
distance = (float) Utils.calculateDistance((int) txPower[0], (double) mRsi);
/** beaconList.add(new String[]{"Name Space ID : " + Utils.bytesToHex(nameSpaceId)+ "\n" + "Instance ID :" + Utils.bytesToHex(instanceId),
String.format("%.2f", distance),
"eddystoneuid"});**/
try {
beaconManager.addEddyBeacon(Utils.bytesToHex(nameSpaceId), Utils.bytesToHex(instanceId), distance);
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
Log.i(TAG, "The size of the frame is: " + eddystoneFrame.getValue().length);
}
} catch (Exception e) {
Log.e("Error123456789", e.toString());
break;
}
}发布于 2021-02-08 14:22:46
蓝牙SIG标准主体定义的蓝牙LE广告有两个变体:
关贸总协定服务广告--这些广告旨在为总协定服务做广告,并且可能有服务数据字节,目的是告诉你有关广告service.
当苹果设计iBeacon格式时,它选择使用制造商广告。因此,无论何时检测到它们,您都必须获得制造商的数据来解码内容。
当谷歌设计Eddystone时,它选择不使用制造商广告,而是使用GATT服务广告。它之所以做出这一选择,是因为它希望他的格式能在iOS设备上很好地工作,而iOS通常拒绝让第三方应用程序在后台检测制造商广告(iBeacon除外)。
由于谷歌的这一设计决策,您必须在尝试解码Eddystone广告时检查是否存在服务数据。
如果要检测这两种信标类型,请使用如下逻辑:
。
https://stackoverflow.com/questions/66102110
复制相似问题