How can I programmatically tell if a Bluetooth device is connected? - android

I understand how to get a list of paired devices, but how can I tell if they are connected?
It must be possible since I see them listed in my phone's Bluetooth device list and it states their connection status.

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 broadcasts
private 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" />

There is an isConnected function in the BluetoothDevice system API in https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth/BluetoothDevice.java.
If you want to know if a bounded (paired) device is currently connected or not, the following function works fine for me:
public static boolean isConnected(BluetoothDevice device) {
try {
Method m = device.getClass().getMethod("isConnected", (Class[]) null);
boolean connected = (boolean) m.invoke(device, (Object[]) null);
return connected;
} catch (Exception e) {
throw new IllegalStateException(e);
}
}

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...
}
};

This code is for the headset profiles, and probably it will work for other profiles too.
First you need to provide a profile listener (Kotlin code):
private val mProfileListener = object : BluetoothProfile.ServiceListener {
override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
if (profile == BluetoothProfile.HEADSET)
mBluetoothHeadset = proxy as BluetoothHeadset
}
override fun onServiceDisconnected(profile: Int) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = null
}
}
}
Then while checking Bluetooth:
mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET)
if (!mBluetoothAdapter.isEnabled) {
return Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
}
It takes a bit of time until onSeviceConnected is called. After that you may get the list of the connected headset devices from:
mBluetoothHeadset!!.connectedDevices

BluetoothAdapter.getDefaultAdapter().isEnabled ->
returns true when Bluetooth is open.
val audioManager = this.getSystemService(Context.AUDIO_SERVICE) as AudioManager
audioManager.isBluetoothScoOn ->
returns true when a device connected

I was really looking for a way to fetch the connection status of a device, not listen to connection events. Here's what worked for me:
BluetoothManager bm = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
List<BluetoothDevice> devices = bm.getConnectedDevices(BluetoothProfile.GATT);
int status = -1;
for (BluetoothDevice device : devices) {
status = bm.getConnectionState(device, BLuetoothGatt.GATT);
// compare status to:
// BluetoothProfile.STATE_CONNECTED
// BluetoothProfile.STATE_CONNECTING
// BluetoothProfile.STATE_DISCONNECTED
// BluetoothProfile.STATE_DISCONNECTING
}

Related

App asks for USB permission on every Phone restart

I'm using an USB-Receiver to handle the Communication with a Temperature Sensor attached via USB to the Phone.
Everything is working fine so far, but if i restart the Phone, the App throws an USB-Permission pop-up directly after restarting, even if there isn't any USB-Device attached to the Phone at that Moment.
Has anyone an Idea of what's causing this strange Problem?
[ EDIT: I'm Sorry, the App isn't asking for USB Permission, the popup asks if i want to Open the app if "this device is connected" but there's obviously no device attached.]
Here is the Code of the USB-Receiver:
//Initial USB Settings Receiver
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
#Override
public void onReceive(final Context context, final Intent intent) {
final String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
final UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
// is usb permission has been granted, try to open a connection
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if (device != null) {
// call method to set up device communication
Constants result = mcp2221.open();
if (result != Constants.SUCCESS) {
//nothing by now
} else {
openConnectionToMCP2221();
}
}
}
}
}
if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
// close the connection and release all resources
closeAllResources();
// leave a bit of time for the COM thread to close
try {
Thread.sleep(20);
}catch(InterruptedException e){e.printStackTrace();}
mcp2221Comm = null;
Toast.makeText(getApplicationContext(), "Device detached",
Toast.LENGTH_SHORT).show();
}
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
final UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) {
Toast.makeText(getApplicationContext(), "Device attached",
Toast.LENGTH_SHORT).show();
mStopUSBThread=false;
// only try to connect if an MCP2221 is attached
if (device.getVendorId() == MCP2221_VID && device.getProductId() == MCP2221_PID) {
Constants result = mcp2221.open();
switch (result) {
case SUCCESS:
openConnectionToMCP2221();
break;
case CONNECTION_FAILED:
Toast.makeText(getApplicationContext(), "ERROR: connection failed", Toast.LENGTH_SHORT).show();
break;
case NO_USB_PERMISSION:
Toast.makeText(getApplicationContext(), "ERROR: no USB permission", Toast.LENGTH_SHORT).show();
mcp2221.requestUsbPermission(mPermissionIntent);
break;
default:
break;
}
}
}
}
}
};
And here is the onCreate() part:
//USB Connection
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
final IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
registerReceiver(mUsbReceiver, filter);
//Checking if theres a Device already connected
.......
Got it!
It was an
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
</intent-filter>
that was declared in AndroidManifest.xml under <activity>.
I don't fully understand, why it caused this Bug, but removing it kept the functionality of my App while getting rid of the Problem.
Only 'negative' aspect might be, that now the App doesn't ask to open if the Sensor is attached to the phone.

android how to get the name of connected bluetooth device [duplicate]

This question already has an answer here:
Android: How to find out name of the bluetooth device connected?
(1 answer)
Closed 6 years ago.
i want to know how to get the name of the connected bluetooth device in android
here is the code
NetworkInfo bluetooth = connectivityManager .getNetworkInfo(ConnectivityManager.TYPE_BLUETOOTH);
if(bluetooth.isConnected())
{
Toast.makeText(myprofile3Context,"bluetooth is connected", Toast.LENGTH_SHORT).show();
}
here i check if bluetooth device is connected or not. if bluetooth is connected i want know how to get the name of connected device.
try this
public String getLocalBluetoothName(){
if(mBluetoothAdapter == null){
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}
String name = mBluetoothAdapter.getName();
if(name == null){
System.out.println("Name is null!");
name = mBluetoothAdapter.getAddress();
}
return name;
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//you can get name by device.getName()
} else if (BluetoothAdapter.ACL_DISCONNECTED
.equals(action)) {
}
}
};
Use extends BroadcastReceiver and add permissions in manifest

Android Connect Bluetooth device automatically after pairing programmatically

In my app I need pairing bluetooth device and immediately connect with it.
I have the following function in order to pairing devices:
public boolean createBond(BluetoothDevice btDevice)
{
try {
Log.d("pairDevice()", "Start Pairing...");
Method m = btDevice.getClass().getMethod("createBond", (Class[]) null);
Boolean returnValue = (Boolean) m.invoke(btDevice, (Object[]) null);
Log.d("pairDevice()", "Pairing finished.");
return returnValue;
} catch (Exception e) {
Log.e("pairDevice()", e.getMessage());
}
return false;
}
And I use it as the following way:
Boolean isBonded = false;
try {
isBonded = createBond(bdDevice);
if(isBonded)
{
//Connect with device
}
}
And it show me the dialog to pairing devices and enter the pin.
The problem is that createBond functions always return true, and it doen's wait until I enter the pin and paired with device, so I don't use correctly:
isBonded = createBond(bdDevice);
if(isBonded) {...}
So the question is How can I paired with device and when it is paired connect to it?
P.D My code is based in the first answer of the following thread: Android + Pair devices via bluetooth programmatically
I found the solution.
First I need a BroadcastReceiver like:
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
// CONNECT
}
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Discover new device
}
}
};
And then I need register the receiver as follow:
IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
context.registerReceiver(myReceiver, intentFilter);
In this way the receiver is listening for ACTION_FOUND (Discover new device) and ACTION_BOND_STATE_CHANGED (Device change its bond state), then I check if the new state is BOND_BOUNDED and if it is I connect with device.
Now when I call createBond Method (described in the question) and enter the pin, ACTION_BOND_STATE_CHANGED will fire and device.getBondState() == BluetoothDevice.BOND_BONDED will be True and it will connect.

notification if the Bluetooth is turned off in android app

Im currently working on a android application.
I have to notify the user whenever the bluetooth of the device is turned off while the application is currently running.
How to notify the remote device that BT is turned off?
Register BroadcastReceiver with intent action BluetoothAdapter.ACTION_STATE_CHANGED and move your notifiyng code into onReceive method. Don't forget to check if new state is OFF
if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
if(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1)
== BluetoothAdapter.STATE_OFF)
// Bluetooth was disconnected
}
If you want to detect when the user is DISCONNECTING his Bluetooth, and later, detect when the user has his Bluetooth DISCONNECTED, you should do the following steps:
1) Get the user BluetoothAdapter:
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
2) Create and configure your Receiver, with a code as this:
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// It means the user has changed his bluetooth state.
if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
if (btAdapter.getState() == BluetoothAdapter.STATE_TURNING_OFF) {
// The user bluetooth is turning off yet, but it is not disabled yet.
return;
}
if (btAdapter.getState() == BluetoothAdapter.STATE_OFF) {
// The user bluetooth is already disabled.
return;
}
}
}
};
3) Register your BroadcastReceiver into your Activity:
this.registerReceiver(mReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));

How to detect if bluetooth device is connected

In android how can my Activity will get to know if a Bluetooth A2DP device is connected to my device.
Is there any broadcast receiver for that?
How to write this broadcast receiver?
Starting from API 11 (Android 3.0) you can use BluetoothAdapter to discover devices connected to a specific bluetooth profile. I used the code below to discover a device by its name:
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.A2DP) {
boolean deviceConnected = false;
BluetoothA2dp btA2dp = (BluetoothA2dp) proxy;
List<BluetoothDevice> a2dpConnectedDevices = btA2dp.getConnectedDevices();
if (a2dpConnectedDevices.size() != 0) {
for (BluetoothDevice device : a2dpConnectedDevices) {
if (device.getName().contains("DEVICE_NAME")) {
deviceConnected = true;
}
}
}
if (!deviceConnected) {
Toast.makeText(getActivity(), "DEVICE NOT CONNECTED", Toast.LENGTH_SHORT).show();
}
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, btA2dp);
}
}
public void onServiceDisconnected(int profile) {
// TODO
}
};
mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.A2DP);
You can do that for every bluetooth profile. Take a look at Working with profiles in Android's guide.
However, as written in other answers, you can register a BroadcastReceiver to listen to connection events (like when you're working on android < 3.0).
You cannot get the list of connected devices by calling any API.
You need instead to listen to the intents ACTION_ACL_CONNECTED, ACTION_ACL_DISCONNECTED that notifies about devices being connected or disconnected.
No way to get the initial list of connected devices.
I had this problem in my app and the way I handle it (didn't find better...) is to bounce off/on the Bluetooth at application start to be sure to start with an empty list of connected devices, and then listen to the above intents.
muslidrikk's answer is broadly correct; however you can alternatively use fetchUUIDsWithSDP() and see what you get back... it's a bit of a hack though -- you'd have to know what UUIDs (capabilities) you could expect from the device, if it were turned on. And that might be difficult to guarantee.
For BluetoothHeadset specifically, you can call getConnectedDevices() to get connected devices for this specific profile.
Reference: http://developer.android.com/reference/android/bluetooth/BluetoothHeadset.html
Other cases you need to register a receiver for that.
In your activity, define broadcast receiver...
// Create a BroadcastReceiver for ACTION_FOUND
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
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
mArrayAdapter.add(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

Categories

Resources