Eddystone设备加速度计数据获取及getBeaconAdvertisementData方法疑问
Hey there! Let's work through your two Eddystone questions with the code snippet you shared to make things concrete.
getBeaconAdvertisementData(beacon) do? This method from the Android Beacon Library acts as a "reverse parser" for a Beacon object. When you use a BeaconParser to convert raw BLE scan data into a structured Beacon instance, this method takes that processed Beacon object and converts it back into a raw byte array that matches the exact Eddystone broadcast format (the same as the original scan data the device sends out).
In your code, you’re calling it right after parsing an Eddystone UID beacon—this would generate the precise byte sequence that your Eddystone device broadcasts for its UID frame. You might use this if you wanted to simulate the beacon’s broadcast, double-check that your parsing logic works correctly, or extract the raw broadcast bytes for custom processing.
Let’s break down why you’re seeing empty getExtraDataFields() and what that c03be53 value means:
First, the root cause of empty extra data
Eddystone accelerometer data is almost always part of Eddystone-TLM (Telemetry) frames, which are separate broadcasts from the UID frames you’re currently parsing. Your code only adds a parser for EDDYSTONE_UID_LAYOUT, so it never picks up the TLM frames that contain the accelerometer data. That’s why getExtraDataFields() returns empty—you’re looking at the wrong frame type entirely.
Fix step 1: Add the TLM parser
First, update your parser list to include the Eddystone-TLM layout so the library can parse those telemetry frames:
ArrayList<BeaconParser> beaconParsers = new ArrayList<BeaconParser>(); // Add both UID and TLM parsers to capture all relevant Eddystone frames beaconParsers.add(new BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT)); beaconParsers.add(new BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_TLM_LAYOUT));
Fix step 2: Distinguish UID vs TLM frames and extract accelerometer data
Eddystone UID and TLM frames broadcast separately, but you can link them to the same device via its MAC address or UID namespace/instance. Here’s how to modify your loop to handle TLM frames and pull accelerometer data:
Beacon beacon = null; for (BeaconParser parser : beaconParsers) { beacon = parser.fromScanData(scanRecord, rssi, device); if (beacon != null && beacon.getServiceUuid() == 0xfeaa) { if (beacon.getBeaconTypeCode() == 0x00) { // This is an Eddystone UID frame (your existing logic remains here) Identifier eddystoneNamespaceId = beacon.getId1(); Identifier eddystoneInstanceId = beacon.getId2(); WirelessDevice wirelessDevice = new WirelessDevice(null, beacon.getRssi(), null, eddystoneNamespaceId.toString()); mainActivity.addDevice(wirelessDevice); byte[] bytes = parser.getBeaconAdvertisementData(beacon); } else if (beacon.getBeaconTypeCode() == 0x20) { // This is an Eddystone TLM frame with telemetry data (including accelerometer) List<Long> extraFields = beacon.getExtraDataFields(); if (extraFields != null && extraFields.size() >= 3) { // TLM frames store accelerometer data as signed 8-bit integers (0.001g per unit) int xRaw = extraFields.get(0).intValue(); int yRaw = extraFields.get(1).intValue(); int zRaw = extraFields.get(2).intValue(); // Convert raw values to g-force measurements float xG = xRaw * 0.001f; float yG = yRaw * 0.001f; float zG = zRaw * 0.001f; // Use the values as needed (example log statement) Log.d("EddystoneAccel", String.format("X: %.3fg, Y: %.3fg, Z: %.3fg", xG, yG, zG)); } } } }
What about that c03be53 value?
That hex string is likely the raw byte data of the accelerometer component from the TLM frame (or a custom extension your device uses). If you ever need to parse raw hex like this manually, convert it to a byte array and interpret each byte as a signed integer:
String accelHex = "c03be5"; // Trimmed trailing 3 to make 3 full bytes for X/Y/Z axes byte[] accelBytes = Hex.decodeHex(accelHex.toCharArray()); int xRaw = (int) accelBytes[0]; // c0 = -64 in signed 8-bit notation int yRaw = (int) accelBytes[1]; // 3b = 59 int zRaw = (int) accelBytes[2]; // e5 = -27 float xG = xRaw * 0.001f; // -0.064g float yG = yRaw * 0.001f; // 0.059g float zG = zRaw * 0.001f; // -0.027g
内容的提问来源于stack exchange,提问作者Nathanael Heitz

