How can I programmatically tell if a Bluetooth device is connected?
Add the Bluetooth permission to your AndroidManifest,
<uses-permission android:name="android.permission.BLUETOOTH" />
Then use intent filters to listen to the ACTION_ACL_CONNECTED
, ACTION_ACL_DISCONNECT_REQUESTED
, and ACTION_ACL_DISCONNECTED
broadcasts:
public void onCreate() { ... IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED); filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); this.registerReceiver(mReceiver, filter);}//The BroadcastReceiver that listens for bluetooth broadcastsprivate final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (BluetoothDevice.ACTION_FOUND.equals(action)) { ... //Device found } else if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) { ... //Device is now connected } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { ... //Done searching } else if (BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED.equals(action)) { ... //Device is about to disconnect } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) { ... //Device has disconnected } }};
A few notes:
- There is no way to retrieve a list of connected devices at application startup. The Bluetooth API does not allow you to query, instead it allows you to listen to changes.
- A hoaky workaround to the above problem would be to retrieve the list of all known/paired devices... then trying to connect to each one (to determine if you're connected).
- Alternatively, you could have a background service watch the Bluetooth API and write the device states to disk for your application to use at a later date.
In my use case I only wanted to see if a Bluetooth headset is connected for a VoIP app. The following solution worked for me.
Kotlin:
fun isBluetoothHeadsetConnected(): Boolean { val mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter() return (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled && mBluetoothAdapter.getProfileConnectionState(BluetoothHeadset.HEADSET) == BluetoothHeadset.STATE_CONNECTED)}
Java:
public static boolean isBluetoothHeadsetConnected() { BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); return mBluetoothAdapter != null && mBluetoothAdapter.isEnabled() && mBluetoothAdapter.getProfileConnectionState(BluetoothHeadset.HEADSET) == BluetoothHeadset.STATE_CONNECTED;}
Of course you'll need the Bluetooth permission:
<uses-permission android:name="android.permission.BLUETOOTH" />
For some reason, BluetoothAdapter.ACTION_ACL_CONNECTED could not be resolved by Android Studio. Perhaps it was deprecated in Android 4.2.2?
Here is a modification of Skylarsutton's code (Big thanks to Skylarsutton for his answer.) . The registration code is the same; the receiver code differs slightly. I use this in a service which updates a Bluetooth-connected flag that other parts of the app reference.
public void onCreate() { //... IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED); filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); this.registerReceiver(BTReceiver, filter); } //The BroadcastReceiver that listens for bluetooth broadcasts private final BroadcastReceiver BTReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) { //Do something if connected Toast.makeText(getApplicationContext(), "BT Connected", Toast.LENGTH_SHORT).show(); } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) { //Do something if disconnected Toast.makeText(getApplicationContext(), "BT Disconnected", Toast.LENGTH_SHORT).show(); } //else if... }};