Big*_*uin 2 bluetooth-lowenergy ibeacon ibeacon-android android-5.0-lollipop
我现在有一个问题,因为我正试图从我的Onyx iBeacon读取tx-Power.我已经阅读了多个建议并在互联网上尝试了这么多代码,但我仍然无法解决这个问题.
我正在使用android棒棒糖,并尝试了来自https://github.com/devunwired/accessory-samples/tree/master/BluetoothGatt的iBeacon教程,
以获取蓝牙应用程序BLUETOOTH_THERM_SERVICE.
我从广告中找到了tx-Power的两个值: 蓝牙LE TX功率读数
0x1804和它的特点0x2A07,所以我改编了包裹UUID来过滤我的ScanResults 0x1804:
public static final ParcelUuid THERM_SERVICE = ParcelUuid.fromString("00001809-0000-1000-8000-00805f9b34fb");
public static final ParcelUuid TX_POWER_SERVICE = ParcelUuid.fromString("00001804-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid ONYX_STANDARD_SERVICE = ParcelUuid.fromString("0000180a-0000-1000-8000-00805f9b34fb");
Run Code Online (Sandbox Code Playgroud)
如教程中所述:
byte[] data = record.getServiceData(TX_POWER_SERVICE);
Run Code Online (Sandbox Code Playgroud)
应该存储一个字节数组,但它总是返回null!唯一存储字节数组的东西,但我认为它存储整个记录是:
byte[] data = record.getServiceData(ONYX_STANDARD_SERVICE);
Run Code Online (Sandbox Code Playgroud)
尝试继续使用我可以获得的数据,ONYX_STANDARD_SERVICE我可以看到scanResult:
onScanResult() - ScanResult{mDevice=78:A5:04:07:AE:96, mScanRecord=ScanRecord [mAdvertiseFlags=6, mServiceUuids=null, mManufacturerSpecificData={76=[2, 21, 32, -54, -24, -96, -87, -49, 17, -29, -91, -30, 8, 0, 32, 12, -102, 102, 0, 7, -82, -106, -78]}, mServiceData={0000180a-0000-1000-8000-00805f9b34fb=[120, -91, 4, 7, -82, -106, -78, 32, -54, -24, -96, 0, 7, -82, -106]}, mTxPowerLevel=-2147483648, mDeviceName=OnyxBeacon], mRssi=-63, mTimestampNanos=174691272168825}
Run Code Online (Sandbox Code Playgroud)
我认为我记录的重要部分是:
mServiceData={0000180a-0000-1000-8000-00805f9b34fb=[120, -91, 4, 7, -82, -106, -78, 32, -54, -24, -96, 0, 7, -82, -106]}
Run Code Online (Sandbox Code Playgroud)
如何从此ServiceData中提取txPower值?我检查了几个应用程序,我的tx-power是-78.
通过使用ONYX_STANDARD_SERVICE检查结果,我可以获得此值scanResult[6] = -78.
这是正确的方法,如果是这样,为什么?
我还在这个问题上找到了一些有趣的例子,其中提到了从记录中读取的另一个值:
如果您在这里查找,您将找到代码:
private static final int DATA_TYPE_TX_POWER_LEVEL = 0x0A;
Run Code Online (Sandbox Code Playgroud)
其中哪一个(0x1804,0x2A07,0x0A)是正确的?
如果有人能够解释我的示例代码是如何THERM_SERVICE工作的,那也很好但不是必要的:
private float parseTemp(byte[] serviceData) {
/*
* Temperature data is two bytes, and precision is 0.5degC.
* LSB contains temperature whole number
* MSB contains a bit flag noting if fractional part exists
*/
float temp = (serviceData[0] & 0xFF);
if ((serviceData[1] & 0x80) != 0) {
temp += 0.5f;
}
return temp;
}
Run Code Online (Sandbox Code Playgroud)
请帮我阅读广告数据并提取tx-Power.
小智 7
可以从广告包获得OnyxBeacon的发送(TX)功率,以及与iBeacon兼容的任何其他BLE设备的发送(TX)功率.这不需要连接到设备.此外,TX功率值将根据功率水平而变化,因为TX功率值针对设备的每个功率水平进行校准.TX功率是广告有效载荷的最后一个字节.有关iBeacon数据包结构的更多信息,请访问:http://www.havlena.net/en/location-technologies/ibeacons-how-do-they-technically-work/
以下是如何解析iBeacon数据包并获取TX功率的示例:
BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice bluetoothDevice, final int rssi, final byte[] scanData) {
if (scanData[7] == 0x02 && scanData[8] == 0x15) { // iBeacon indicator
System.out.println("iBeacon Packet: %s", bytesToHexString(scanData));
UUID uuid = getGuidFromByteArray(Arrays.copyOfRange(scanData, 9, 25));
int major = (scanData[25] & 0xff) * 0x100 + (scanData[26] & 0xff);
int minor = (scanData[27] & 0xff) * 0x100 + (scanData[28] & 0xff);
byte txpw = scanData[29];
System.out.println("iBeacon Major = " + major + " | Minor = " + minor + " TxPw " + (int)txpw + " | UUID = " + uuid.toString());
}
}
};
public static String bytesToHexString(byte[] bytes) {
StringBuilder buffer = new StringBuilder();
for(int i=0; i<bytes.length; i++) {
buffer.append(String.format("%02x", bytes[i]);
}
return buffer.toString();
}
public static UUID getGuidFromByteArray(byte[] bytes)
{
ByteBuffer bb = ByteBuffer.wrap(bytes);
UUID uuid = new UUID(bb.getLong(), bb.getLong());
return uuid;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4529 次 |
| 最近记录: |