You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Eddystone设备加速度计数据获取及getBeaconAdvertisementData方法疑问

Hey there! Let's work through your two Eddystone questions with the code snippet you shared to make things concrete.

1. What does 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.

2. How to correctly retrieve accelerometer data from your Eddystone device?

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:49:07