android BLE获取广告数据包中编码的uuid

7d7tgy0s  于 2023-01-11  发布在  Android
关注(0)|答案(5)|浏览(232)

我试图获得ble设备的UUID。我是按照Android开发人员指南,到目前为止,我只能获得设备名称和RSSI。我试图获得设备的UUID,扫描方法看起来像这样:

public void onLeScan(final BluetoothDevice device, int rssi,byte[] scanRecord) {

        ParcelUuid[] myUUid =device.getUuids();
        for(ParcelUuid a :myUUid){
            Log.d("UUID",a.getUuid().toString());
        }
        String s = new String(scanRecord);
        int len = scanRecord.length;
        String scanRecords =new String(scanRecord) ;


        deviceMap.put(device.getName().toString(), rssi);
        Message msg = MainActivity.myHandler.obtainMessage();
        Bundle bundle = new Bundle();
        bundle.putCharSequence("dev_name", device.getName().toString());
        bundle.putCharSequence("rssi", Integer.toString(rssi));
        msg.setData(bundle);
        MainActivity.myHandler.sendMessage(msg);
   }

这将返回- btif_gattc_upstreams_evt:事件4096

pqwbnv8z

pqwbnv8z1#

如果您想在BLE扫描后从scanRec[]字节中获取UUID /任何其他数据,例如制造商数据,您首先需要了解这些广告数据包的数据格式。
来自Bluetooth.org:x1c 0d1x
太多的理论,想看看一些代码片段吗?下面的函数将直接打印解析后的原始数据字节。现在,您需要了解每种类型的代码,以了解什么数据包引用什么信息。例如,类型:0x 09,指BLE设备名称,类型:0x 07,表示UUID。

public void printScanRecord (byte[] scanRecord) {

    // Simply print all raw bytes   
    try {
        String decodedRecord = new String(scanRecord,"UTF-8");
        Log.d("DEBUG","decoded String : " + ByteArrayToString(scanRecord));
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    // Parse data bytes into individual records
    List<AdRecord> records = AdRecord.parseScanRecord(scanRecord);

    // Print individual records 
    if (records.size() == 0) {
        Log.i("DEBUG", "Scan Record Empty");
    } else {
        Log.i("DEBUG", "Scan Record: " + TextUtils.join(",", records));
    }

}

public static String ByteArrayToString(byte[] ba)
{
  StringBuilder hex = new StringBuilder(ba.length * 2);
  for (byte b : ba)
    hex.append(b + " ");

  return hex.toString();
}

public static class AdRecord {

    public AdRecord(int length, int type, byte[] data) {
        String decodedRecord = "";
        try {
            decodedRecord = new String(data,"UTF-8");

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        Log.d("DEBUG", "Length: " + length + " Type : " + type + " Data : " + ByteArrayToString(data));         
    }

    // ...

    public static List<AdRecord> parseScanRecord(byte[] scanRecord) {
        List<AdRecord> records = new ArrayList<AdRecord>();

        int index = 0;
        while (index < scanRecord.length) {
            int length = scanRecord[index++];
            //Done once we run out of records
            if (length == 0) break;

            int type = scanRecord[index];
            //Done if our record isn't a valid type
            if (type == 0) break;

            byte[] data = Arrays.copyOfRange(scanRecord, index+1, index+length);

            records.add(new AdRecord(length, type, data));
            //Advance
            index += length;
        }

        return records;
    }

    // ...
}

经过这种解析之后,这些数据字节将变得更有意义,您可以计算出下一级的解码。

tvokkenx

tvokkenx2#

正如评论中提到的,BLE设备实际上没有特定的UUID(但包含的服务有很多UUID)。然而,一些方案(如iBeacon)在广告数据包中的制造商特定数据记录中编码唯一标识符。
下面是一种效率非常低但概念简单的方法,可以将整个scanRecord转换为十六进制字符串表示形式,以便进行调试打印:

String msg = "payload = ";
for (byte b : scanRecord)
  msg += String.format("%02x ", b);

注意,这将包括实际的通告分组和多个无意义的尾部字节,在解析通告分组本身中包含的结构(长度字段)之后,应当忽略这些尾部字节。

vcirk6k6

vcirk6k63#

我在开发我的ble应用程序时遇到了同样的问题,但在阅读了以下链接上的文档后:https://developer.android.com/reference/android/bluetooth/le/ScanResult.html
就UUID(取决于你开发的API)而言,重要的类是:
播发数据播发数据.Builder扫描记录扫描结果
在阅读了这些类的文档之后,我编写了以下代码来获取任何被扫描设备的UUID:
//对于API〈21:

private BluetoothAdapter.LeScanCallback scanCallBackLe =
        new BluetoothAdapter.LeScanCallback() {
            @Override
            public void onLeScan(final BluetoothDevice device, int rssi, final byte[] scanRecord) {
                final int RSSI = rssi;
                if (RSSI >= signalThreshold){
                    scanHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            AdvertiseData data = new AdvertiseData.Builder()
                                    .addServiceUuid(ParcelUuid
                                            .fromString(UUID
                                                    .nameUUIDFromBytes(scanRecord).toString())).build();
                            scannerActivity.addDevice(device, RSSI, getUUID(data));
                        }
                    });
                }
            }
        };

//For APIs less than 21, Returns Device UUID
public String getUUID(AdvertiseData data){
    List<ParcelUuid> UUIDs = data.getServiceUuids();
    //ToastMakers.message(scannerActivity.getApplicationContext(), UUIDs.toString());
    String UUIDx = UUIDs.get(0).getUuid().toString();
    Log.e("UUID", " as list ->" + UUIDx);
    return UUIDx;
}

对于API〉21:

private ScanCallback mScanCallback = new ScanCallback() {
    @Override
    public void onScanResult(int callbackType, final ScanResult result) {
        Log.i("callbackType", String.valueOf(callbackType));
        Log.i("result", result.toString());
        final int RSSI = result.getRssi();
        if (RSSI>=signalThreshold) {
            scanHandler.post(
                    new Runnable() {
                        @Override
                        public void run() {
                            BluetoothDevice device = result.getDevice();
                            scannerActivity.addDevice(device, result.getRssi(), getUUID(result));
                        }
                    });
        }
    } ...}

//For APIs greater than 21, Returns Device UUID
public String getUUID(ScanResult result){
    String UUIDx = UUID
            .nameUUIDFromBytes(result.getScanRecord().getBytes()).toString();
    ToastMakers.message(scannerActivity.getApplicationContext(), UUIDx);
    Log.e("UUID", " as String ->>" + UUIDx);
    return UUIDx;
}

我能够使用此代码获得任何设备的128位UUID。:)

x0fgdtte

x0fgdtte5#

您可以使用标准的Android蓝牙GattCharacteristicAPI,如 getFloatValue(整数格式类型,整数偏移量),getIntValue(整数格式类型,整数偏移量),getStringValue(整数偏移量)..参考非常好的Android开发者网站教程here

if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
        int flag = characteristic.getProperties();
        int format = -1;
        if ((flag & 0x01) != 0) {
            format = BluetoothGattCharacteristic.FORMAT_UINT16;
            Log.d(TAG, "Heart rate format UINT16.");
        } else {
            format = BluetoothGattCharacteristic.FORMAT_UINT8;
            Log.d(TAG, "Heart rate format UINT8.");
        }
        final int heartRate = characteristic.getIntValue(format, 1);
        Log.d(TAG, "Received heart rate: " + heartRate);
        intent.putExtra(EXTRA_DATA, String.valueOf(heartRate));
    }

相关问题