【问题标题】:Retrieving Android BluetoothLE device information (Major / minor / identifier / ProximityUUID) on scan?在扫描时检索 Android BluetoothLE 设备信息(主要/次要/标识符/ProximityUUID)?
【发布时间】:2014-07-21 15:37:47
【问题描述】:

我一直在环顾四周,不幸的是,android ibeacon 库已被弃用,所以我正在尝试做这个原生的。我已经实现了 BluetoothAdapter.LeScanCallback 和内置的 onLeScan() 方法,该方法将在设备被拾取时触发。我想阅读该设备的 ProximityUUID、主要和次要特征以及标识符。我不确定如何从 Android 对象 BluetoothDevice 中获取该信息。

如何从 Android BluetoothDevice 中提取该信息(ProximityUUID、主要、次要和标识符特征),或者有其他方法吗?

谢谢!

【问题讨论】:

标签: android bluetooth-lowenergy ibeacon


【解决方案1】:

您可以参考此post 以完全了解这些字节在 LeScanCallback 中的含义。 这是我解析所有所需信息的代码:

// an object with all information embedded from LeScanCallback data
public class ScannedBleDevice implements Serializable {
    // public BluetoothDevice BLEDevice;

    /**
    * Returns the hardware address of this BluetoothDevice.
    * <p>
    * For example, "00:11:22:AA:BB:CC".
    * 
    * @return Bluetooth hardware address as string
    */
    public String MacAddress;

    public String DeviceName;
    public double RSSI;
    public double Distance;

    public byte[] CompanyId;
    public byte[] IbeaconProximityUUID;
    public byte[] Major;
    public byte[] Minor;
    public byte Tx;

    public long ScannedTime;
}

// use this method to parse those bytes and turn to an object which defined proceeding.
// the uuidMatcher works as a UUID filter, put null if you want parse any BLE advertising data around.
private ScannedBleDevice ParseRawScanRecord(BluetoothDevice device,
        int rssi, byte[] advertisedData, byte[] uuidMatcher) {
    try {
        ScannedBleDevice parsedObj = new ScannedBleDevice();
        // parsedObj.BLEDevice = device;
        parsedObj.DeviceName = device.getName();
        parsedObj.MacAddress = device.getAddress();
        parsedObj.RSSI = rssi;
        List<UUID> uuids = new ArrayList<UUID>();
        int skippedByteCount = advertisedData[0];
        int magicStartIndex = skippedByteCount + 1;
        int magicEndIndex = magicStartIndex
                + advertisedData[magicStartIndex] + 1;
        ArrayList<Byte> magic = new ArrayList<Byte>();
        for (int i = magicStartIndex; i < magicEndIndex; i++) {
            magic.add(advertisedData[i]);
        }

        byte[] companyId = new byte[2];
        companyId[0] = magic.get(2);
        companyId[1] = magic.get(3);
        parsedObj.CompanyId = companyId;

        byte[] ibeaconProximityUUID = new byte[16];
        for (int i = 0; i < 16; i++) {
            ibeaconProximityUUID[i] = magic.get(i + 6);
        }

        if (uuidMatcher != null) {
            if (ibeaconProximityUUID.length != uuidMatcher.length) {
                Log.e(LOG_TAG,
                        "Scanned UUID: "
                                + Util.BytesToHexString(
                                        ibeaconProximityUUID, " ")
                                + " filtered by UUID Matcher "
                                + Util.BytesToHexString(uuidMatcher, " ")
                                + " with length requirment.");
                return null;
            }

            for (int i = 0; i < 16; i++) {
                if (ibeaconProximityUUID[i] != uuidMatcher[i]) {
                    Log.e(LOG_TAG,
                            "Scanned UUID: "
                                    + Util.BytesToHexString(
                                            ibeaconProximityUUID, " ")
                                    + " filtered by UUID Matcher "
                                    + Util.BytesToHexString(uuidMatcher,
                                            " "));
                    return null;
                }
            }

        }

        parsedObj.IbeaconProximityUUID = ibeaconProximityUUID;

        byte[] major = new byte[2];
        major[0] = magic.get(22);
        major[1] = magic.get(23);
        parsedObj.Major = major;

        byte[] minor = new byte[2];
        minor[0] = magic.get(24);
        minor[1] = magic.get(25);
        parsedObj.Minor = minor;

        byte tx = 0;
        tx = magic.get(26);
        parsedObj.Tx = tx;

        parsedObj.ScannedTime = new Date().getTime();
        return parsedObj;
    } catch (Exception ex) {
        Log.e(LOG_TAG, "skip one unknow format data...");
        // Log.e(LOG_TAG,
        // "Exception in ParseRawScanRecord with advertisedData: "
        // + Util.BytesToHexString(advertisedData, " ")
        // + ", detail: " + ex.getMessage());
        return null;
    }
}

【讨论】:

  • 所以澄清一下,没有像 BluetoothDevice.getMajor() 或类似的东西吗?我知道我在文档中没有看到它,但我非常希望它不会解析字节数组。尽管如此,您的回答还是很有帮助的,谢谢。
  • @Andrew 不,这些不起作用,不适用于此“BLE 广告数据”场景解析。
【解决方案2】:
  1. 应将广告数据包的有效负载解析为 AD 结构的列表
  2. iBeacon是一种AD结构。

详见“iBeacon as a kind of AD structures”。另外,请参阅answer 来回答类似问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 2012-06-24
    相关资源
    最近更新 更多