代码之家  ›  专栏  ›  技术社区  ›  Escher

Bluetooth LE ScanResult返回null,但我知道我的外设正在广播心率服务UUID(经第三方BLE应用程序验证)。为什么?

  •  0
  • Escher  · 技术社区  · 5 年前

    我的BLE扫描没有返回GATT服务UUID(即 scanRecord.getServiceUUIDs() 退货 null ). 但是,我知道我的心率外设工作正常,广告也正常,因为心率服务是由LightBlue应用程序发现的(并且可读)。 这是我的职责 ScanCallback

    override fun onScanResult(callbackType: Int, result: ScanResult?) {
        super.onScanResult(callbackType, result)
        // This log shows that result.mServiceUuids is null
        Log.i(TAG, "BLEDeviceManager.ScanCallback.onScanResult: ${result.toString()}")
    
        // TODO: handle null ScanResult
        val parcelUuids = if (result.getScanRecord() != null) result.getScanRecord()!!.getServiceUuids() else null
        if (parcelUuids == null) {
            Log.i(TAG, "parcelUUids was null for scanRecord = ${result.getScanRecord()!!.toString()}")
            return
        }
        val serviceList = ArrayList<UUID>()
        for (i in parcelUuids.indices) {
            val serviceUUID = parcelUuids.get(i).getUuid()
            if (!serviceList.contains(serviceUUID))
                serviceList.add(serviceUUID)
        }
        Log.i(TAG, "Here is a list of the service UUIDs: $serviceList")
    }
    

    日志如下:

    I/BLEDeviceManager:scanRecord=scanRecord[mAdvertiseFlags=6,mServiceUuids=null,MserviceRequestationUuids=null,MmanufacturersSpecificData={},mServiceData={},mTxPowerLevel=3,mDeviceName=blehr\u sensor\u 1.0]的Parceluids为null

    我做错了什么以至于 mServiceUuids 始终为空?

    0 回复  |  直到 5 年前
        1
  •  1
  •   Martijn van Welie    5 年前

    根据您输出的ScanRecord,您的设备没有公布任何服务UUID。这并不意味着它没有这项服务……它只是不做广告而已。

    您可能需要连接到它,然后调用discoverServices()以获取它真正拥有的服务列表。。。

        2
  •  0
  •   Codo    5 年前

    您的设备可能会播发无效数据。如果是这样,即使无效数据位于不相关的字段中,Android也会返回一个空的服务列表。

    因此,请分析广告数据并检查您要查找的UUID。一旦你了解了发生了什么,你就可以自己解析数据了。

    (下面的代码是Java而不是Kotlin。但是Android Studio应该自动转换它。)

    @Override
    public void onScanResult(int callbackType, ScanResult result) {
        super.onScanResult(callbackType, result);
        ScanRecord scanRecord = result.getScanRecord();
        byte[] advertisementData = scanRecord.getBytes();
        Log.i(TAG, "advertisement data: " + bytesToHex(advertisementData));
    }
    
    private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
    
    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = HEX_ARRAY[v >>> 4];
            hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
        }
        return new String(hexChars);
    }