I am trying to disable the Bluetooth from my code but it remains enabled and no errors are thrown.
Here is my code.
if (m_BluetoothAdapter.isEnabled()){
m_BluetoothAdapter.disable();
}
if (m_BluetoothAdapter.isEnabled() == false){
Toast.makeText(getApplicationContext(), "BLUETOOTH is being disabled", Toast.LENGTH_SHORT).show();
}
This is the only code in my app for testing.
I also put permission for Bluetooth and Bluetooth_admin.
Neither Eclipse nor mobile gives any error but BT remains enable.
Pl point me what I am doing wrong.
Regards
Update :
Well, I discovered that if I run this app 1st time, BT remains enable.
But if I run app again (2nd time), BT is disabled.
I am not sure why BT is disabled only on the 2nd run and not first time.
Any ideas?
You should know that disable() method makes an asynchronous call so for this reason your code seems not working.
In other words it takes some time when bluetooth will be disabled. In this case you should use BroadcastReceiver with BluetoothAdapter.ACTION_STATE_CHANGED intent-filter and listen for state changes and then make proper actions.
Available states STATE_ON STATE_TURNING_OFF and STATE_OFF
Also look what says docs:
true to indicate adapter shutdown has begun, or false on immediate
error
Use this library , its easy to use and more friendly
also try with below code
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.disable();
}
Related
I'm trying to create a bond between my Android phone and my device. Before they were connected well by calling device.connectGatt() with my gattCallback. But now as I want to also want to add bonding by calling device.createBond(), my onConnectionStateChange shows an alternate pattern of connected and disconnected with the status code 0 when connected and 8 when disconnected. Here is my snippet of code of how I'm trying to use connectGatt and createBond together.
#Override
public void onScanResult(int callbackType, ScanResult result) {
System.out.println("on scan result");
super.onScanResult(callbackType, result);
BluetoothDevice device = result.getDevice();
synchronized (this) {
if (mBluetoothGatt == null) {
if (device.createBond()) {
System.out.println("create bond success");
mBluetoothGatt = device.connectGatt(mListener.retrieveApplicationContext(), true, mGattCallback);
}
else System.out.println("create bond sb");
}
}
}
Is there anything wrong by calling these two methods in this way? I searched the internet for creating bonds but none of the pages uses createBond and connectGatt together. I only got a hint from this post about how to call these two methods this way: Android BLE onCharacteristicChanged() using notify not triggered
Also, my BroadCastReceiver always shows device bonding as well but never shows device bonded.
The createBond method will internally first connect to the device if not connected using autoConnect set to false. That means the bonding attempt will be aborted after 30 seconds if the device never connects successfully during that time. But you connect using autoConnect set to true, which means no timeout. So if it for some reason takes 31 seconds to connect, the bonding will not happen.
If I were you, I'd first connect the device myself, and when the device has successfully connected and services discovered (and checked that it has the desired services), call createBond, to make sure everything seems right before bonding.
Status code 8 means "Connection Timeout". This means the connection was up and running but dropped unexpectedly on the radio level, which is not a software error, but something that happens naturally as you go out of range but also due to bad hw such as buggy firmware or bad crystal clock frequency.
I am developing an Android app which searches for Classic and Low Energy Bluetooth devices such that when I press "search" button it will show me all Bluetooth devices (low energy and classic) in range. Since classic BT discovery and LE scanning are different things, I have to implement them separately and combine them in one function such that
searchFirstLowEnergyThenClassic() or searchFirstClassicThenLowEnergy()
In order to implement this, I have to know when the discovery/scanning ends so that I immediately start scan/discovery for other technology.
Here is my implementation:
Started Classic BT discovery
Received BluetoothAdapter.ACTION_DISCOVERY_FINISHED
Started BLE Scaning -> onReceive action equals(ACTION_DISCOVERY_FINISHED)
Stop search when BLE Scan ended
This looks ok but there is a problem when I extend the behavior. When I want search, I start searching first with LE scan or Classic discovery based on the last connected technology. For example if last time the device is connected to a Classic BT device, searchFirstClassicThenLowEnergy() is run. Otherwise, searchFirstLowEnergyThenClassic().
So as you might guess, it gets more complicated. For example, when the Classic BT discovery ends, the app should know whether the search ended or it should proceed with LE scan.
There is also this issue. When the user stops search during the scan/discovery of first technology, it will recieve BluetoothAdapter.ACTION_DISCOVERY_FINISHED but it shouldn't start LE scan since the search is terminated by user.
I implemented this using some flags (not working properly, though) but my code looks very dirty.
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
// Classic Bluetooth discovery ended
lastOpenedType = getLastOpenedType();
if (lastOpenedType == BT_CLASSIC && !isSearchStoppedByUser()) {
// Search should continue with low energy scan
startBtLeScanning();
} else if (lastOpenedType != BT_CLASSIC && !isSearchStoppedByUser()){
// Search ended
searchProgressLayout.setVisibility(View.INVISIBLE);
} else {
// Search ended by user
searchProgressLayout.setVisibility(View.INVISIBLE);
}
}
In short, I am asking if someone has a more brilliant and simple solution on this?
PS. A solution without broadcast intent is much appreciated if possible.
BluetoothAdapter's startDiscovery() method searches for both classic and BLE devices. Once you get the result from the scan, you can separate them based on the type of the device. For example:
int deviceType = device.getType();
if(deviceType == BluetoothDevice.DEVICE_TYPE_CLASSIC)
{
}
else if(deviceType == BluetoothDevice.DEVICE_TYPE_LE)
{
}
else if(deviceType == BluetoothDevice.DEVICE_TYPE_DUAL)
{
}
So, it's not needed to search separately.
startLESCan is more advanced and better method of scanning bluetooth devices with some advancements like take less energy consumption.
I've a simple service to pair bluetooth devices and it look like this:
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
if(!extras.containsKey("bluetoothAddress"))
return;
String bluetoothAddress = extras.getString("bluetoothAddress");
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if(!adapter.isEnabled()) {
adapter.enable();
}
BluetoothDevice device = adapter.getRemoteDevice(bluetoothAddress);
device.createBond();
}
It works perfectly fine except that sometimes the pair dialogue pop up and sometimes it show up in my notifications bar and I have to open it manually. Is there any way to make sure that it always pop up to the front?
I've tried to google on it and only thing I can find is that if you stay in bluetooth settings it always pop up, but that seems like a ugly solution. The reason for all of this is that I'm working with automation and want to make sure that when I run my service I get the pair dialogue can just click "Pair".
I had the same problem. I've found this post that explains when the dialog is shown or not: Bluetooth pairing request on notification bar?
Resuming, it depends on the result of the shouldShowDialogInForeground() method.
Quoting from the post:
... there are ways of making the dialog show:
If the device was in discoverable mode recently
If the device was discovering recently
If the device was picked in the device picker recently
If Bluetooth Settings is visible
In my case to force the dialog to appear, I started and canceled a discovery before trying to pair...
Code/Hack
BluetoothAdapter.getDefaultAdapter().startDiscovery();
//Give it some time before cancelling the discovery
Thread.sleep(1000);
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
//Then do the LeScan and connect to the device
PS:I know it's a horrible hack but is the only way I got this to work, and the pairing must be done only once for device so it's not so terrible... Also, if anybody finds a better way I'm open to suggestions
I use following code to resolve the issue
if(!BluetoothAdapter.getDefaultAdapter().isDiscovering())
BluetoothAdapter.getDefaultAdapter().startDiscovery();
//make sure that the device is in discovering
while (!BluetoothAdapter.getDefaultAdapter().isDiscovering());
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
I'm developing an Android app that has to exchange some data through BT by automatically create a communication between two devices. To do so the only way (I've found) is to first make the device find each other and then negotiate a master who will open a ServerSocket and host the connection.
My problem then is how to toggle BT discoverability without prompting the request to the user!
I've searched the net with no success, so I start thinking about possible solution.
First I thought about something like a BroadcastReceiver that would catch the request instead the default activity launched by StartActivity(new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE)), but then I wouldn't know what to do to actually make the device discoverable.
Recently I've thought about hiding or dismissing the dialog raised by the precedent call by automatically selecting the positive button. Once again I've no clue on how to do it!
Any help will be really appreciate, thank you in advance to everyone and sorry for my bad English!
I can't point to any explicit documentation, but I'm pretty sure you're not allowed to silently turn on and off Bluetooth in android. Bluetooth discoverability is something that at the end of the day is always up to the user. To subvert their authority presents a huge security concern.
You can call .enable() on an instance of BluetoothAdapter
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.enable();
I am trying to disconnect bluetooth by using
if (bluetoothAdapter != null) {
if(bluetoothAdapter.isEnabled()|bluetoothAdapter.isDiscovering()){
bluetoothAdapter.disable();
bluetoothAdapter.cancelDiscovery();
}
}
But it is not working.Can anyone suggest something on that which will be fruitful for me.
If you are disconnecting you should try and disconnect your specific connection rather than turning off bluetooth.. turning off will cause other active connections (which you might not have created also to disconnect)
If this is what you want i.e to disconnect every thing, then in the code above you should first cancel Discovery then Disable.
To do both of these you need the BLUETOOTH_ADMIN privilege.