Click here to Skip to main content
15,885,244 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am having a real problem here with discovering bluetooth devices. I am making a method that returns a List with all devices that were discovered. This method triggers other methods that executes the discovery and establish the BroadcastReceivers. THE PROBLEM is that the method returns before the BroadcastReceivers finds the devices. This results in returning an empty list every time by the getDiscoveredList() because the List hasn't been filled yet by the Receivers. List made global where all methods and Receivers share the same List. The List is filled with devices after the method returns.

Here is my code: ArrayList discoveredDevices = new ArrayList();

public ArrayList<device> getDiscoveredList() {

    isDiscovering = true;
    monitorDiscovery();

    discoverDevices();

    Log.d("Save",
            "Before - btAdapter.isDiscovering()"
                    + btAdapter.isDiscovering());
    while (btAdapter.isDiscovering()) {
        // Waiting for discovery to end. Assuming that during discovery
        // devices have already been added
        // in discoveredDevices because they are added when
        // BluetoothDevice.ACTION_FOUND
        // When discovery ends, no nearby devices is expected to be found by
        // the
        // discoveryResult BroadcastReceiver because I am not discovering
        // outside this loop
    }

    Log.d("Save",
            "After - btAdapter.isDiscovering()" + btAdapter.isDiscovering());
    Log.d("Save", "Returning from getDiscoveredList()");
    return discoveredDevices;
}

private void monitorDiscovery() {
    registerReceiver(discoveryMonitor, new IntentFilter(
            BluetoothAdapter.ACTION_DISCOVERY_STARTED));
    registerReceiver(discoveryMonitor, new IntentFilter(
            BluetoothAdapter.ACTION_DISCOVERY_FINISHED));
}

private void discoverDevices() {

    while (!btAdapter.isEnabled()) { // If Bluetooth is still opening, then
                                        // wait till opened
    }
    discoveredDevices.clear(); // Clear the List
    btAdapter.startDiscovery();
    while (!btAdapter.isDiscovering()) { // Wait till discovery starts
    }
    BroadcastReceiver discoveryResult = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            BluetoothDevice remoteDevice;
            remoteDevice = intent
                    .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            short rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,
                    Short.MIN_VALUE);

            Toast.makeText(
                    getApplicationContext(),
                    "Discovered: " + remoteDevice.getName() + "  RSSI: "
                            + rssi, Toast.LENGTH_SHORT).show();

            if (!discoveredDevices.contains(remoteDevice)) {
                discoveredDevices.add(new Device(remoteDevice, rssi));
                Log.d("Save", "Name: " + remoteDevice.getName());
                Log.d("Save", "Address: " + remoteDevice.getAddress());
                Log.d("Save", "RSSI: " + rssi);
                Log.d("Save", "Size Now: " + discoveredDevices.size());
            }
        }
    };
    registerReceiver(discoveryResult, new IntentFilter(
            BluetoothDevice.ACTION_FOUND));

    return;
}

BroadcastReceiver discoveryMonitor = new BroadcastReceiver() {

    String dStarted = BluetoothAdapter.ACTION_DISCOVERY_STARTED;
    String dFinished = BluetoothAdapter.ACTION_DISCOVERY_FINISHED;

    @Override
    public void onReceive(Context context, Intent intent) {
        if (dStarted.equals(intent.getAction())) {
            // Discovery has started.
            Log.d("Save", "Discovery Started...");
        } else if (dFinished.equals(intent.getAction())) {
            Log.d("Save", "Discovery Finished...");
            Log.d("Save", "doneDiscovering()     isDiscovering = false");
            isDiscovering = false;
            Log.d("Save", "Discovery Completed...discoveredDevices Size = "
                    + discoveredDevices.size());
            for (int i = 0; i < discoveredDevices.size(); i++) {
                Log.d("Save", "Device(" + i + "): "
                        + discoveredDevices.get(i).getDevice().getName()
                        + "  RSSI= " + discoveredDevices.get(i).getRssi());
            }
            Log.d("Save",
                    "Size at doneDiscovering() :"
                            + discoveredDevices.size());
        }
    }
};</device>


Monitoring the LogCat, the getDiscoveredList() method is executed and returns before the BroadcastReceiver discoveryMonitor or the BroadcastReceiver discoveryResult does anything although they are triggered within this method, and it is ensured by the LogCat that the discovery starts and ends before returning.

I JUST CAN'T UNDERSTAND how can discovery starts and ends before saving the discovered devices or event logging "Discovery Started..." and "Discovery Completed..." which is logged when the intentAction is startedDiscovery or endedDiscovery. It looks as the program is insisting to complete the method getDiscoveredList() before monitoring the bluetooth discovery because I tried to pause the method until the devices are saved or so, but this didn't do nothing. The method was paused, then after that it returned then the discovery work happened!

PLEASE I need help because I am so desperate with this problem. I have tried every single turn-around I am aware of, but nothing happened. It seems because I don't know something about the order these methods or Receivers work in.
Posted
Updated 8-Jul-11 14:54pm
v3
Comments
Dr.Walt Fair, PE 8-Jul-11 20:56pm    
I put some tags in to make your code more readable.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900