1

Im trying to discover bluetooth low energy devices but I have a problem with onLeScan method. It is getting called twice and as a result all devices doubled.

Method that i use to initiate scanning:

private void scanLeDevice(final boolean enable) {
        if (enable) {
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    bluetoothAdapter.stopLeScan(getLeScanCallback());
                    scanning = false;
                }
            }, SCAN_PERIOD);

            scanning = true;
            bluetoothAdapter.startLeScan(getLeScanCallback());
        } else {
            bluetoothAdapter.stopLeScan(getLeScanCallback());
            scanning = false;
        }
    }

Method returning LeScanCallback:

private BluetoothAdapter.LeScanCallback getLeScanCallback(){
        BluetoothAdapter.LeScanCallback leScanCallback =
                new BluetoothAdapter.LeScanCallback() {
                    @Override
                    public void onLeScan(final BluetoothDevice bluetoothDevice, int rssi
                            , byte[] scanRecord) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Log.d(TAG, "device found");
                                Device device = new Device();
                                device.setName(bluetoothDevice.getName());
                                device.setAddress(bluetoothDevice.getAddress());
                                devices.add(device);
                                deviceListAdapter.notifyDataSetChanged();
                            }
                        });
                    }
                };

        return leScanCallback;
    }
Michał Witanowski
  • 602
  • 3
  • 8
  • 22
  • 1
    There's probably not enough code posted to diagnose the problem. Try debugging and set a breakpoint on getLeScanCallback to see if it is getting called 2x. Also, sometimes devices will be found twice in a scan. So you need to check if they are already in devices before adding – David Rawson Dec 02 '16 at 09:01
  • getLeScanCallback isn't called twice but you are correct I should check for duplicates. I thought that each device can be discovered only once. Thank you for help. – Michał Witanowski Dec 02 '16 at 09:09

2 Answers2

9

Yes, the BLE devices may appear several times during a scan cycle if their advertising cycle is frequent enough compared to the scan cycle. So you should identify each BLE device (maybe with the name or address) and add them to your list only once. You could keep a separate list of recently seen beacons or just check if devices already contains the found device and avoid adding duplicates. (Or use a Set instead of List.) Just update any data (like RSSI if you show it) if the BLE device already exists in the list. You'll probably need to override equals() and hashCode() in Device to make either List.contains() or a Set work properly

Markus Kauppinen
  • 3,025
  • 4
  • 20
  • 30
0

I know this was asked a long time ago and I am posting my solution here. The problem with the code is that scanLeDevice(true) is called in protected void onResume(). Why this is called twice ? have a look over here Why is my onResume being called twice?

You just need to update your logic here.

if (!scanning ) {
//If not scanning start scanning
 mLeDeviceListAdapter = new LeDeviceListAdapter();
            // setListAdapter(mLeDeviceListAdapter);
            dialog = ProgressDialog.show(AdjActivity.this, "Searching for the Ring",
                    "Scanning for Ring. Please wait...", true);
            scanLeDevice(true);
}
Afnan Bashir
  • 7,319
  • 20
  • 76
  • 138