John
John

Reputation: 89

Bluetooth enabling disrupts broadcastreceiver

My app is designed to append all scanned Bluetooth devices to a textview. This works great if the phones Bluetooth is on. However, if my app checks to see if the phones Bluetooth is off and turns it on if it is off, then start my the discovery process my broadcastreciever does not pick up an event and so my textview does not populate. Any help is appreciated!

Here is my code:

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

    txtResults = (TextView) this.findViewById(R.id.txtResults);
    mBlueToothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (!(mBlueToothAdapter.isEnabled())) {
        mBlueToothAdapter.enable(); 

    }           

    mBlueToothAdapter.startDiscovery();

MY RECEIVER:

public static class BlueToothBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        BluetoothDevice device = intent
                .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

        blueToothName = device.getName();
        blueToothAddress = device.getAddress();
        blueToothClass = device.getBluetoothClass();
        blueToothBondState = device.getBondState();
        GetBondStateStr(blueToothBondState);
        blueToothUUIDS = device.getUuids();

        paramsBlueTooth
                .add(new BasicNameValuePair("Name: ", blueToothName));
        paramsBlueTooth.add(new BasicNameValuePair("Address: ",
                blueToothAddress));
        paramsBlueTooth.add(new BasicNameValuePair("Class: ", String
                .valueOf(blueToothClass)));
        paramsBlueTooth.add(new BasicNameValuePair("Bond State: ",
                blueToothBondStateStr));
        paramsBlueTooth.add(new BasicNameValuePair("UUIDS: ", String
                .valueOf(blueToothUUIDS)));

        showBlueToothData();

    }

ShowBlueToothData():

    private void showBlueToothData() {
        StringBuilder results = new StringBuilder();

        results.append("-----BLUETOOTH DEVICE INFORMATION-----\n");
        results.append("Name: " + blueToothName + "\n");
        results.append("Address: " + blueToothAddress + "\n");
        results.append("Class: " + blueToothClass + "\n");
        results.append("Bond State: " + blueToothBondStateStr + "\n");
        results.append("UUIDS: " + blueToothUUIDS + "\n");

        txtResults.append(new String(results));
        txtResults.append("\n");
    }

Upvotes: 0

Views: 59

Answers (2)

devunwired
devunwired

Reputation: 63293

Your chosen method of enabling the Bluetooth radio via the BluetoothAdapter.enable() method is an asynchronous call. As you can see from the method's documentation, you cannot assume that the radio is up and active as soon as the method returns. You have to wait for the ACTION_STATE_CHANGED broadcast to know that the radio is ready for you to try a scan.

If you read the documentation, notice also that doing it this was is a poor experience because there is no notification to the user. A better choice is the method of sending the user to Settings to enable Bluetooth themselves. You could modify your startup logic to be something more like this:

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

    txtResults = (TextView) this.findViewById(R.id.txtResults);
    mBlueToothAdapter = BluetoothAdapter.getDefaultAdapter();

    …
}

@Override
protected void onResume() {
    super.onResume();
    if (!(mBlueToothAdapter.isEnabled())) { 
        //Take the user to settings first!
        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivity(intent);
    } else {
        mBlueToothAdapter.startDiscovery();
    }
}

This modification will check for Bluetooth every time you come to the foreground, and only trigger the scan if you are ready to do so.

Upvotes: 2

RE60K
RE60K

Reputation: 621

Try doing:

Intent enable_intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enable_intent, REQUEST_ENABLE_BT);

inside if (!(mBlueToothAdapter.isEnabled())){...}

OR:

for(int i=0;i<5;i++){
   if (!mBluetoothAdapter.isEnabled()) {
    mBluetoothAdapter.enable(); 
   }
   Thread.sleep(100);
}else{
//display error, unsuccessfull , try manually
}

Upvotes: 0

Related Questions