Android 4.3: BLE: Filtering behaviour of startLeScan() Android 4.3: BLE: Filtering behaviour of startLeScan() android android

Android 4.3: BLE: Filtering behaviour of startLeScan()


With Android 4.3 and 4.4 so far, it appears to be a mess: Some devices call onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) multiple times for one device in one scan, some don't. There is no way to configure the filtering like in iOS (see answer of Arkadiusz Konior). So, I now start a list, because I can't ask my users such a question about their device.

However, restarting scaning is also no problem on "not filtering" devices. So, I restart scaning on every device now.

Not filtering (Continuously calling onLeScan())

  • Samsung Galaxy S4 with 4.2.2 using Samsung BLE sdk (I owned that device)
  • Nexus 5 with 4.4 (added by [vegarwe]. The device will give scan records continuously for nearby devices while scanning)
  • Samsung Galaxy S3 with 4.3 (JSS15J.I9300XXUGMK6, I was testing on that device)
  • Samsung Galaxy S4 with 4.3 and 4.4.2 using Android SDK (added by arnaud.b, no build provided)
  • HTC One with 4.4.2 (added by arnaud.b, no build number provided)

Filtering devices (applies to Standard)

  • Nexus 4 with 4.3, 4.4 (I own that device)
  • Nexus 7 2013 4G with 4.4.2 (KOT49H, I was testing on that device)
  • Samsung Galaxy S4 mini with 4.2.2 (I was testing on this device)
  • Motorola Moto X (added by user1603602, no information about android version provided)
  • Motorola Moto G with 4.3 (falcon_umts, My testing device)
  • Sony Xperia Tablet Z Wifi with Android 4.3 (Build 10.4.B.0.577, Model SGP311, my testing device)
  • OnePlus One with 5.0.1 and 5.1.1 (Cyanogen 12.1)

Unknown filtering behavior (Please help to associate the device to a certain group)

  • Nexus 7 2013 (Different behavior is reported like here. But I have read more reports that it's belonging to first group.)
  • Other SAMSUNG, HTC, Motorola, ..., devices


The text in pages 2535-2536 in the Bluetooth specification (Core_v4.1.pdf) about duplicate advertising reports is somewhat unclear. However the text on page 1258 is clear. It specifies a Filter_Duplicates parameter to the HCI_LE_Set_Scan_Enable command. In Android version 4.4 (Kitkat) this parameter is 0x00 (Duplicate filtering disabled).

There is a simple way to find out if any filtering is done in the Bluetooth chip from Android versions 4.4 (Kitkat). Make the phone a developer phone, enter developer options and check “Enable Bluetooth HCI snoop log”. Then turn Bluetooth OFF and ON once to make the settings bite. From now on all HCI packets between the application processor and the Bluetooth chip will be stored on the phone in a file which is pulled by adb pull storage/emulated/legacy/btsnoop_hci.log . This is not a text file and you need a program from http://www.fte.com/products/default.aspx or wireshark to view btsnoop_hci.log. For wireshark you need a pretty recent version, because older versions does not support BLE. My experience is that there is never any filtering in the Bluetooth chip, i.e. the HCI Event “LE Advertising Report Event” is sent for every ADV_IND and ADV_NONCONN_IND that the Bluetooth chip receives. This goes for phones with Bluetooth chips Qualcomm/Atheros WCN 3680 and Broadcom BCM 4339.

Correction: the path to btsnoop_hci.log can be different depending on the phone manufacturer. You can find the correct path by adb shell cat etc/bluetooth/bt_stack.conf | grep BtSnoopFileName


I'm developing the application for Android 4.3 (Nexus 4&7) using BLE and from my observations scanning returns the same device multiple times if there was no SCAN REQUEST send back to the peripheral.

Device may advertise in 2 ways: passive and active. In passive mode the peripheral device is just advertising all of it's data and doesn't listen after sending periodic packet. It's just sending, sleeping, sending, sleeping...In active mode the sensor also advertises but the message is as short as possible. After sending it it switches to listening for some very short time. When scanned detects the short message, it immediately sends SCAN REQUEST command to the peripheral and gets response with more details. As far as I can see Android doesn't sent SCAN REQUEST multiple times during one scanning.

Let's assume that we have 2 devices in range. One is f.e. Nordic's nRF Temp sensor (passive advertising) and one other connectible device. I've received the following scan response:

11-10 21:32:54.281: D/BluetoothAdapter(13468): startLeScan(): null11-10 21:32:54.281: D/BluetoothAdapter(13468): onClientRegistered() - status=0 clientIf=411-10 21:32:54.321: D/BluetoothAdapter(13468): onScanResult() - Device=CD:61:1A:A8:BC:BE RSSI=-9411-10 21:32:55.122: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-6111-10 21:32:56.414: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-6211-10 21:32:57.715: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-6111-10 21:32:59.016: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-6311-10 21:33:01.609: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-6311-10 21:33:02.901: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-6311-10 21:33:04.212: D/BluetoothAdapter(13468): onScanResult() - Device=CB:32:81:CF:FD:00 RSSI=-6211-10 21:33:04.282: D/BluetoothAdapter(13468): stopLeScan()

As you can see the connectible device showed up just once while the other one 7 times.

Another question I would like to resolve is how rapidly the scanning can be switched on and off. Scanning is a power intensive operation, yet the broadcast of data will happen periodically on a fairly precise, real time timer. As a result, it would be a great optimization if the scan can be switched on and off, such that the broadcast and scan are synchronized, with the scanner shut down the other 90%+ of the time. This will likely need to be tested experimentally.

Scanning frequency depends on the device. Furthermore advertising is usually done on 3 channels: 37, 38 and 39 to increase probability of being found. However this might be quite good idea to get advertising packets from 'active' devices multiple times.