1

I'm writing an app to turn on bluetooth, scan for bluetooth-discoverable devices nearby including paired and not paired in order to add them to a list.

Here is my code:

public class Main extends Activity {

    private BluetoothAdapter ba;
    private Set<BluetoothDevice>pairedDevices;

    private ListView lv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        lv = (ListView)findViewById(R.id.bluetooth_device_listview);

        initiate();
    }

    public void initiate() {

        ba = BluetoothAdapter.getDefaultAdapter();

        if (ba == null) {

            // Device does not support Bluetooth
            AlertDialog.Builder localBuilder = new AlertDialog.Builder(this);

            localBuilder.setTitle("No Bluetooth Support");
            localBuilder.setMessage("Device does not support Bluetooth feature.\nThis"
                    + "will quit the application.");
            localBuilder.setCancelable(false);

            localBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener()
            {
              public void onClick(DialogInterface paramAnonymousDialogInterface, int     paramAnonymousInt)
              { 
                Main.this.finish();
              }
            });

            localBuilder.create().show();
        }
    }

    public void turnOn(View view) {

        if (!ba.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, 0);

            if(ba.isEnabled())
                Toast.makeText(getApplicationContext(), "Turned On", 
                        Toast.LENGTH_SHORT).show();

            scan();

        } else
            Toast.makeText(getApplicationContext(), "Already On", 
                    Toast.LENGTH_LONG).show();
    }

    public void scan() {        

        final ArrayList<String> deviceList = new ArrayList<String>();

        if (ba.isDiscovering()) ba.cancelDiscovery();

        ba.startDiscovery();

        // Get a list of paired devices

        pairedDevices = ba.getBondedDevices();

        for(BluetoothDevice bt : pairedDevices)
            deviceList.add(bt.getName() + "\n" + bt.getAddress() + "\n" + "Paired");

        /*********************************************************************/

        // Scan for other devices

        final BroadcastReceiver receiver = new BroadcastReceiver() {

            public void onReceive(Context context, Intent intent) {

                String action = intent.getAction();

                if (BluetoothDevice.ACTION_FOUND.equals(action)) {

                    BluetoothDevice device =     intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                    deviceList.add(device.getName() + "\n" + device.getAddress()
                            + "\n" + "Not Paired");
                }
            }
        };

        final ArrayAdapter<String> adapter = new ArrayAdapter<String>
        (this, android.R.layout.simple_list_item_1, deviceList);

        lv.setAdapter(adapter);

        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        registerReceiver(receiver, filter);
    }
}

The code seems fine, but it doesn't find or adds any nearby devices to list and when I quit the app, I get following exception log:

12-12 12:53:59.818: E/ActivityThread(5097): Activity net.adeveloper.testdeviate.Main has leaked IntentReceiver net.adeveloper.testdeviate.Main$2@4055c128 that was originally registered here. Are you missing a call to unregisterReceiver()?
12-12 12:53:59.818: E/ActivityThread(5097): android.app.IntentReceiverLeaked: Activity net.adeveloper.testdeviate.Main has leaked IntentReceiver net.adeveloper.testdeviate.Main$2@4055c128 that was originally registered here. Are you missing a call to unregisterReceiver()?
12-12 12:53:59.818: E/ActivityThread(5097):     at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:799)
12-12 12:53:59.818: E/ActivityThread(5097):     at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:575)
12-12 12:53:59.818: E/ActivityThread(5097):     at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:865)
12-12 12:53:59.818: E/ActivityThread(5097):     at android.app.ContextImpl.registerReceiver(ContextImpl.java:852)
12-12 12:53:59.818: E/ActivityThread(5097):     at android.app.ContextImpl.registerReceiver(ContextImpl.java:846)
12-12 12:53:59.818: E/ActivityThread(5097):     at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:318)
12-12 12:53:59.818: E/ActivityThread(5097):     at net.adeveloper.testdeviate.Main.scan(Main.java:132)
12-12 12:53:59.818: E/ActivityThread(5097):     at net.adeveloper.testdeviate.Main.turnOn(Main.java:83)
12-12 12:53:59.818: E/ActivityThread(5097):     at java.lang.reflect.Method.invokeNative(Native Method)
12-12 12:53:59.818: E/ActivityThread(5097):     at java.lang.reflect.Method.invoke(Method.java:507)
12-12 12:53:59.818: E/ActivityThread(5097):     at android.view.View$1.onClick(View.java:2187)
12-12 12:53:59.818: E/ActivityThread(5097):     at android.view.View.performClick(View.java:2533)
12-12 12:53:59.818: E/ActivityThread(5097):     at android.view.View$PerformClick.run(View.java:9320)
12-12 12:53:59.818: E/ActivityThread(5097):     at android.os.Handler.handleCallback(Handler.java:587)
12-12 12:53:59.818: E/ActivityThread(5097):     at android.os.Handler.dispatchMessage(Handler.java:92)
12-12 12:53:59.818: E/ActivityThread(5097):     at android.os.Looper.loop(Looper.java:150)
12-12 12:53:59.818: E/ActivityThread(5097):     at android.app.ActivityThread.main(ActivityThread.java:4385)
12-12 12:53:59.818: E/ActivityThread(5097):     at java.lang.reflect.Method.invokeNative(Native Method)
12-12 12:53:59.818: E/ActivityThread(5097):     at java.lang.reflect.Method.invoke(Method.java:507)
12-12 12:53:59.818: E/ActivityThread(5097):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
12-12 12:53:59.818: E/ActivityThread(5097):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)
12-12 12:53:59.818: E/ActivityThread(5097):     at dalvik.system.NativeStart.main(Native Method)

Any idea to fix the problems?

To add paired devices to the list view, I have to add a button and associate it with scan() method. That's frustrating, I want to populate the list when I hit "Turn On" button. Besides, finding not paired devices still remains.

Ali Allahyar
  • 341
  • 2
  • 11
  • 22
  • register your receiver in @Override protected void onResume() { super.onResume(); Log.i(TAG, "On Resume ....."); } – sakir Dec 12 '14 at 14:38

4 Answers4

1

You have forgot to unregister the BroadcastReceiver.Some advice here:

1.You can register your BroadcastReceiver in the onCreate() and unregister your BroadcastReceiver in the onDestroy().

2.Try to start discovering bluetooth device after you register your BroadcastReceiver.

3.Remember that there will occur that the same BluetoothDevice return by the BroadcastRecevier,this is related to the mechanism of Bluetooth discovering.Normally you need to filter by mac address.

I'm confused that what do you mean:I want to populate the list when I hit "Turn On" button. Besides, finding not paired devices still remains.?

When you hit "Turn On" button, you just do one thing that you check the Bluetooth whether turned on or not. Then you use startActivityForResult to popup a system window to remind user you need to turn on Bluetooth and then discovery the online bluetooth device and get the paired device. You don't modify the list of paired bluetooth devices ,maybe you find more or less unpaired bluetooth devices.

ifeegoo
  • 7,054
  • 3
  • 33
  • 38
0

According to the answer below, you are supposed to override the onStop method in the BroadcastReceiver and call unregisterReceiver() to get rid of those logcat errors.

https://stackoverflow.com/a/14357640/3250699

However, I don't think that will fix the discovery problem. To ensure that discovery is getting started, can you try checking the return on ba.startDiscovery()? According to the Android Docs, the method..."[startDiscovery()] Returns true on success, false on error".

The docs also mention "Requires BLUETOOTH_ADMIN." so ensure that this permission is set in the AndroidManifest.xml

Android SDK Docs: http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#startDiscovery()

Community
  • 1
  • 1
andromation
  • 106
  • 1
  • 4
  • Yeah, the logcat exception problem resolved when I immediately unregistered receiver after populating list, but still the main problem remains. I've edited my question. please take a look... – Ali Allahyar Dec 12 '14 at 10:31
  • I added bluetooth permissions at the beginning of project. They don't seem to be the problem... – Ali Allahyar Dec 12 '14 at 10:33
0

For the more recent Android versions you also need to add <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> to the AndroidManifest.xml.

See this reference

Cassie
  • 5,223
  • 3
  • 22
  • 34
0

I also encountered this problem. But the problem was not in the code it is due to I didn't granted the location permission to the app. after granting permission it is showing all nearby available devices