23 June, 2014

BLE: How to parse local name from scan record

Maybe you think there is a way to get local name from remote ble device:
BluetoothDevice.getName(), right?
Actually it is wrong. Why?
1, It is device dependent. Not all the device models will return the local name for you.
2, It will be cached. This name will be cached by Bluetooth stack.

So how to get local name correctly:

We have to get local name from adv data, and we cannot get name when there is no name advertised especially when the ble device is in the background.

Here is the method:
 static String parseName(byte[] advData) {
  int ptr = 0;

  while (ptr < advData.length - 2) {
   int length = advData[ptr++] & 0xff;
   if (length == 0)
    break;

   final int ad_type = (advData[ptr++] & 0xff);

   switch (ad_type) {
   case 0xff:
    break;
   case 0x08:
   case 0x09:
    byte[] name = new byte[length - 1];
    int i = 0;
    length = length - 1;
    while (length > 0) {
     length--;
     name[i++] = advData[ptr++];
    }
    String nameString = new String(name);

    return nameString;
   }
   ptr += (length - 1);
  }
  return null;
 }