I am developing an Android application that heavily relies on Bluetooth connectivity. I’ve implemented a BroadcastReceiver to listen for changes in the Bluetooth state, specifically monitoring the BluetoothAdapter.ACTION_STATE_CHANGED intent to detect when the Bluetooth adapter is turning off or has turned off.
Here is a snippet of my code:
private final BroadcastReceiver bluetoothStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
switch (state) {
case BluetoothAdapter.STATE_TURNING_OFF:
// Handle Bluetooth turning off
handleBluetoothTurningOff();
break;
case BluetoothAdapter.STATE_OFF:
// Handle Bluetooth being off
handleBluetoothOff();
break;
}
}
}
};
I have captured logs with ADB to ensure that the device is not emitting the desired Intent:
08-12 14:28:10.369 5868 5868 D BluetoothGatt: connect() - device: 00091F_A, auto: false
08-12 14:28:10.370 5868 5868 D BluetoothGatt: registerApp()
08-12 14:28:10.371 5868 5868 D BluetoothGatt: registerApp() - UUID=fc7486f2-6fe9-4101-a439-d6f0498067d1
08-12 14:28:10.383 5868 5901 D BluetoothGatt: onClientRegistered() - status=0 clientIf=5
08-12 14:28:15.421 5868 5901 D BluetoothGatt: onClientConnectionState() - status=133 clientIf=5 device=00091F_A
08-12 14:28:15.444 5868 5901 D BluetoothGatt: close()
08-12 14:28:15.451 5868 5901 D BluetoothGatt: unregisterApp() - mClientIf=5
08-12 14:28:21.162 13313 13438 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.163 1624 1639 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.163 2970 2990 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.163 5868 16206 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.164 1270 1431 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.164 3258 6357 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.165 1957 3863 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.165 1605 5864 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.166 13001 13024 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.166 13026 16208 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.185 13313 13438 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.186 1605 5864 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.186 1270 1431 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.186 5868 16206 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.186 2970 2990 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.186 3258 6357 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.186 13001 13024 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.186 1624 1639 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.187 13026 16208 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.187 1957 4130 D BluetoothAdapter: onBluetoothServiceDown
08-12 14:28:21.188 1957 4556 I BluetoothAdapter: BluetoothAdapter() : com.google.android.gms
08-12 14:28:21.212 1957 4790 I BluetoothAdapter: STATE_OFF=10
08-12 14:28:21.215 1957 4790 I BluetoothAdapter: STATE_OFF=10
08-12 14:28:21.215 1957 4790 D BluetoothLeScanner: stop scan is not allowed as BT is off
08-12 14:28:21.217 1270 1270 I BluetoothAdapter: STATE_OFF=10
08-12 14:28:21.228 1270 1270 I BluetoothAdapter: STATE_OFF=10
08-12 14:28:21.244 1270 1270 I BluetoothAdapter: STATE_OFF=10
08-12 14:28:21.245 1270 1270 I BluetoothAdapter: STATE_OFF=10
08-12 14:28:21.246 5868 5868 I BluetoothAdapter: STATE_OFF=10
08-12 14:28:21.246 5868 5868 D BluetoothLeScanner: stop scan is not allowed as BT is off
08-12 14:28:21.253 5868 5868 I BluetoothAdapter: STATE_OFF=10
08-12 14:28:21.253 5868 5868 D BluetoothLeScanner: stop scan is not allowed as BT is off
08-12 14:28:21.253 5868 5868 I BluetoothAdapter: STATE_OFF=10
08-12 14:28:21.253 5868 5868 D BluetoothLeScanner: stop scan is not allowed as BT is off
08-12 14:28:21.253 5868 5868 I BluetoothAdapter: STATE_OFF=10
08-12 14:28:21.253 5868 5868 D BluetoothLeScanner: stop scan is not allowed as BT is off
08-12 14:28:21.253 5868 5868 I BluetoothAdapter: STATE_OFF=10
08-12 14:28:21.253 5868 5868 D BluetoothLeScanner: stop scan is not allowed as BT is off
08-12 14:28:21.253 5868 5868 I BluetoothAdapter: STATE_OFF=10
08-12 14:28:21.253 5868 5868 D BluetoothLeScanner: stop scan is not allowed as BT is off
08-12 14:28:21.267 1957 4790 I BluetoothAdapter: STATE_OFF=10
08-12 14:28:21.408 1957 1957 I BluetoothAdapter: BluetoothAdapter() : com.google.android.gms
08-12 14:28:22.006 16228 16228 I BluetoothAdapter: BluetoothAdapter() : com.android.bluetooth
08-12 14:28:22.204 13313 13832 D BluetoothAdapter: onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@687270d
08-12 14:28:22.204 1605 5864 D BluetoothAdapter: onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@c42db05
08-12 14:28:22.204 2970 8098 D BluetoothAdapter: onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@9f044fb
08-12 14:28:22.205 5868 15214 D BluetoothAdapter: onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@c313804
08-12 14:28:22.205 1270 1431 D BluetoothAdapter: onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@75b5a99
08-12 14:28:22.205 1624 1639 D BluetoothAdapter: onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@8eff7df
08-12 14:28:22.206 1957 3863 D BluetoothAdapter: onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@5e00d03
08-12 14:28:22.206 3258 4734 D BluetoothAdapter: onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@5004e05
08-12 14:28:22.208 13001 13024 D BluetoothAdapter: onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@e28ae0a
08-12 14:28:22.208 13026 13306 D BluetoothAdapter: onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@3de93fe
08-12 14:28:22.209 16228 16240 D BluetoothAdapter: onBluetoothServiceUp: com.android.bluetooth.btservice.AdapterService$AdapterServiceBinder@dd932f7
08-12 14:28:22.246 1270 1270 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.274 1957 4790 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.731 13026 13026 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.731 13026 13026 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.731 13026 13026 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.731 13026 13026 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.735 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.735 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.735 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.735 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.739 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.740 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.740 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.740 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.743 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.743 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.743 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.743 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.746 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.746 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.746 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.746 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.747 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.747 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.747 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.747 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.748 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.748 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.748 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.748 1624 1773 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.749 13026 13026 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.749 13026 13026 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.749 13026 13026 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.749 13026 13026 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.755 13026 13026 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.755 13026 13026 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.756 13026 13026 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.756 13026 13026 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.765 13026 13026 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.765 13026 13026 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.765 13026 13026 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.765 13026 13026 I BluetoothAdapter: STATE_OFF=14
08-12 14:28:22.774 13026 13026 I BluetoothAdapter: STATE_BLE_ON
08-12 14:28:22.775 13026 13026 I BluetoothAdapter: STATE_BLE_ON
08-12 14:28:22.775 13026 13026 I BluetoothAdapter: STATE_BLE_ON
08-12 14:28:22.775 13026 13026 I BluetoothAdapter: STATE_BLE_ON
08-12 14:28:22.782 1270 1270 I BluetoothAdapter: STATE_BLE_ON
08-12 14:28:22.782 1270 1270 I BluetoothAdapter: appoCount is = 1
08-12 14:28:22.783 1270 1270 I BluetoothAdapter: STATE_BLE_ON
08-12 14:28:22.783 1270 1270 I BluetoothAdapter: appoCount is = 1 G/S = 1/0
08-12 14:28:22.787 13026 13026 I BluetoothAdapter: STATE_TURNING_ON
08-12 14:28:22.788 13026 13026 I BluetoothAdapter: STATE_TURNING_ON
08-12 14:28:22.789 13026 13026 I BluetoothAdapter: STATE_TURNING_ON
08-12 14:28:22.789 13026 13026 I BluetoothAdapter: STATE_TURNING_ON
08-12 14:28:22.797 1270 1270 I BluetoothAdapter: STATE_TURNING_ON
08-12 14:28:22.818 1270 1270 I BluetoothAdapter: STATE_TURNING_ON
08-12 14:28:22.886 16228 16228 I BluetoothAdapter: BluetoothAdapter() : com.android.bluetooth
08-12 14:28:23.041 16228 16228 I BluetoothAdapter: BluetoothAdapter() : com.android.bluetooth
08-12 14:28:23.058 16228 16228 D BluetoothAdapter: listenUsingL2capOn: set assigned channel to 4097
08-12 14:28:23.296 1957 4790 I BluetoothAdapter: STATE_TURNING_ON
In most cases, this setup works as expected. However, I’ve noticed that sometimes the BluetoothAdapter does not emit the STATE_TURNING_OFF intent at all. This leads to situations where my app is not notified that Bluetooth is turning off, and therefore, it cannot react appropriately (e.g., by cleaning up resources or notifying the user).
This behavior seems inconsistent, and I haven’t been able to identify a pattern or specific conditions under which the intent is not emitted.
My Questions:
- Why does the BluetoothAdapter sometimes fail to emit the STATE_TURNING_OFF intent?
- Are there known circumstances or limitations that could prevent this intent from being broadcasted?
- What are the best practices to ensure my app reliably detects when the Bluetooth adapter is turning off?
- I have seen that the method onBluetoothServiceDown from a private static callback inside BluetoothAdapter is being called, is it a good idea to access this private callback? (Through reflection, for example)
I’ve considered adding a fallback mechanism, such as periodically polling the BluetoothAdapter state, but I’m looking for a better understanding of the root cause and if there’s a more robust solution.
Any insights or suggestions would be greatly appreciated!
Juan Paños Basterra is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.