杂记(解决Android扫描BLE设备名称不刷新问题)

智慧并不产生于学历,而是来自对于知识的终生不懈的追求。这篇文章主要讲述杂记:解决Android扫描BLE设备名称不刷新问题相关的知识,希望能为你提供帮助。
背景
个人开发过一种BLE设备有这样一种需求:当设备处于状态A时,广播设备名称A;处于状态B时,广播设备名称B。
 
问题
我们发现,当android在进行Ble扫描的时候,扫描回调函数onScanResult中获取的设备名称并未随设备实时改变。
但是当使用nrfConnect进行扫描时,却发现设备广播名称确实是实时改变的。
 
原因
我们使用如下代码获取BLE设备名称,然而此时device.getName()中的名称是系统缓存的数据,而非实时的广播数据,要想获取实时的设备名称,必须自行解码实时广播数据。

1private ScanCallback mScanCallback = new ScanCallback() { 2@Override 3public void onScanResult(int callbackType, ScanResult result) { 4 5BluetoothDevice device = result.getDevice(); 6if(null != device & & null != device.getName()) { 7Log.d("test", device.getName()); // not the real name 8} 9} 10 11 12@Override 13public void onScanFailed(int errorCode) { 14super.onScanFailed(errorCode); 15} 16 17};

 
解决
通过分析BLE广播包协议,自行解码出设备名称。
1private ScanCallback mScanCallback = new ScanCallback() { 2@Override 3public void onScanResult(int callbackType, ScanResult result) { 4 5BluetoothDevice device = result.getDevice(); 6if(null != device & & null != device.getScanRecord().getBytes()) { 7byte[] scanRecord = device.getScanRecord().getBytes(); // advertised data 8String realName = parseDeviceName(scanRecord); 9} 10} 11 12 13@Override 14public void onScanFailed(int errorCode) { 15super.onScanFailed(errorCode); 16} 17 18};

 
杂记(解决Android扫描BLE设备名称不刷新问题)

文章图片
杂记(解决Android扫描BLE设备名称不刷新问题)

文章图片
1// return name String(successful) or null(failed) 2public static String parseDeviceName(byte[] scanRecord) { 3String ret = null; 4if(null == scanRecord) { 5return ret; 6} 7 8ByteBuffer buffer = ByteBuffer.wrap(scanRecord).order(ByteOrder.LITTLE_ENDIAN); 9while (buffer.remaining() > 2) { 10byte length = buffer.get(); 11if (length == 0) 12break; 13 14byte type = buffer.get(); 15length -= 1; 16switch (type) { 17case 0x01: // Flags 18buffer.get(); // flags 19length--; 20break; 21case 0x02: // Partial list of 16-bit UUIDs 22case 0x03: // Complete list of 16-bit UUIDs 23case 0x14: // List of 16-bit Service Solicitation UUIDs 24while (length > = 2) { 25buffer.getShort(); 26length -= 2; 27} 28break; 29case 0x04: // Partial list of 32 bit service UUIDs 30case 0x05: // Complete list of 32 bit service UUIDs 31while (length > = 4) { 32buffer.getInt(); 33length -= 4; 34} 35break; 36case 0x06: // Partial list of 128-bit UUIDs 37case 0x07: // Complete list of 128-bit UUIDs 38case 0x15: // List of 128-bit Service Solicitation UUIDs 39while (length > = 16) { 40long lsb = buffer.getLong(); 41long msb = buffer.getLong(); 42length -= 16; 43} 44break; 45case 0x08: // Short local device name 46case 0x09: // Complete local device name 47byte sb[] = new byte[length]; 48buffer.get(sb, 0, length); 49length = 0; 50ret = new String(sb).trim(); 51return ret; 52case (byte) 0xFF: // Manufacturer Specific Data 53buffer.getShort(); 54length -= 2; 55break; 56default: // skip 57break; 58} 59if (length > 0) { 60buffer.position(buffer.position() + length); 61} 62} 63return ret; 64}

View Code 
 
 
参考资料:
【杂记(解决Android扫描BLE设备名称不刷新问题)】https://www.race604.com/ble-advertising/

    推荐阅读