I need to do a scan of bluetooth devices in the surrounding area for 6 to 12 seconds. After this time I need to stop the discovery of new devices.
The following code should:
The problem is that the bluetooth discovery is never cancelled. After this code runs for a minute or two, onReceive will get called tens of times in the same second...
public void startTrackingButton(View view) {
Log.d("MAIN", "Track button pressed, isTracking: " + !isTracking);
if (isTracking) {
isTracking = false;
} else {
isTracking = true;
Thread keepScanning = new Thread(new Runnable() {
@Override
public void run() {
while (isTracking) {
if (mBluetoothAdapter.isDiscovering()) {
Log.d("MAIN", "Cancelling discovery!");
Log.d("MAIN", String.valueOf(mBluetoothAdapter.cancelDiscovery() + ":" + mBluetoothAdapter.getState()));
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}
startTracking();
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
keepScanning.start();
}
}
private void startTracking() {
Log.d("MAIN", "Starting Discovery...");
mBluetoothAdapter.startDiscovery();
// Create a BroadcastReceiver for ACTION_FOUND
BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
Log.d("MAIN", "Device Found...");
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a
// ListView
Log.d("MAIN:",
device.getName() + "\n" + device.getAddress());
}
}
};
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // Don't forget to unregister
// during onDestroy
}
Here is my logcat output:
//onReceive gets called many times in the same second???
05-01 22:09:56.949: D/MAIN(3757): Cancelling discovery!
05-01 22:09:56.969: D/MAIN(3757): false:12 ///THIS SHOULD BE TRUE
05-01 22:09:56.969: D/MAIN(3757): Starting Discovery...
05-01 22:10:03.009: D/MAIN(3757): Starting Discovery...
05-01 22:10:03.579: D/MAIN(3757): Device Found...
05-01 22:10:03.579: D/MAIN:(3757): TOMSELLECK
05-01 22:10:03.579: D/MAIN:(3757): 06:07:08:09:A1:A1
05-01 22:10:03.579: D/MAIN(3757): Device Found...
05-01 22:10:03.579: D/MAIN:(3757): TOMSELLECK
05-01 22:10:03.579: D/MAIN:(3757): 06:07:08:09:A1:A1
05-01 22:10:03.589: D/MAIN(3757): Device Found...
05-01 22:10:03.589: D/MAIN:(3757): TOMSELLECK
05-01 22:10:03.589: D/MAIN:(3757): 06:07:08:09:A1:A1
05-01 22:10:03.589: D/MAIN(3757): Device Found...
05-01 22:10:03.589: D/MAIN:(3757): TOMSELLECK
05-01 22:10:03.589: D/MAIN:(3757): 06:07:08:09:A1:A1
05-01 22:10:03.589: D/MAIN(3757): Device Found...
05-01 22:10:03.589: D/MAIN:(3757): TOMSELLECK
05-01 22:10:03.589: D/MAIN:(3757): 06:07:08:09:A1:A1
Does anybody know how I can properly cancel all current and pending Bluetooth discovery??
Thanks for your help!
P.S The reason I need to repeat the process is to get fresh signal strength values from nearby devices.
It's also easy to disable Bluetooth from the Settings app, but it takes a few more taps. To do it, open Settings and navigate to Connected Devices > Connection Preferences > Bluetooth and turn off the switch beside “Use Bluetooth.”
Tap Settings. Tap Bluetooth. Tap the indicator next to "Bluetooth" to turn the function on or off. Tap the indicator next to "Open detection" to turn Bluetooth visibility on or off.
The BluetoothAdapter lets you perform fundamental Bluetooth tasks, such as initiate device discovery, query a list of bonded (paired) devices, instantiate a BluetoothDevice using a known MAC address, and create a BluetoothServerSocket to listen for connection requests from other devices, and start a scan for Bluetooth ...
Every time you call startTracking()
, you create and register another BroadcastReceiver
. Thus, after you have called startTracking()
ten times, you have ten receivers waiting for devices. Once a device is found, all these receivers get notified, which explains why you get so many log entries.
Regarding cancelDiscovery
returning false, the bluetooth code of Android is probably its most buggy part. Look what I found. Never assume anything related to Bluetooth on Android will work correctly across different versions and devices. For debug purposes, you can add a listener for BluetoothAdapter.ACTION_DISCOVERY_FINISHED
. Maybe isDiscovering()
will return false after cancelling, but I could imagine there being a short delay between the cancel request and isDiscovering()
returning false.
YOUR PERSONAL BUG RECOMMENDATIONS Customers who encountered this bug also enjoyed:
EXTRA_DISCOVERABLE_DURATION
and can only enable discoverability for 120 seconds. This should be fixed by 2.3.6, but I saw it happen on a Samsung Galaxy Ace with 2.3.6, so maybe Samsung broke it or it wasn't fixed after all. Doesn't happen on my 4.x devices though.Also note: Since you use Thread.sleep
, the thread will probably pause more than 6 seconds of real time, since time as measured by Thread.sleep
stops when the CPU sleeps. Depending on how the device behaves while scanning, this may be much more than 6 seconds. If you want to use real-time based timing, you will have to use an AlarmManager, which unfortunately is a pain in the ass - you will probably want to write a thin wrapper for it.
I don't recommend canceling discovery. This is buggy in Android. On the Nexus 4's I have, canceling sometimes causes bluetooth to be disabled until a reboot and in some of the worst cases until a factory reset. I recommend letting discovery finish and then restarting as soon as it is over.
Discovery doesn't take long anyway, although it varies based on the number of devices seen durring discovery. Here's a scan with 8 devices:
05-07 16:47:53.655: I/MANAGER:BluetoothManager(22019): Bluetooth Discovery Starting...
05-07 16:48:13.687: I/MANAGER:BluetoothManager(22019): Bluetooth Discovery Finished...
Note that if you run discovery all the time you will drain the battery pretty fast.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With