Can someone teach me how can I find out if bluetooth is connected to other device (mobile, headset, etc.)
I don't know of any way to get a list of currently connected devices, but you can listen for new connections using the ACL_CONNECTED intent:
http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#ACTION_ACL_CONNECTED
This intent includes an extra field with the remote device that the connection is with.
On Android, all Bluetooth connections are ACL connections, so registering for this intent will get you all new connections.
So, your receiver would look something like this:
public class ReceiverBlue extends BroadcastReceiver {
public final static String CTAG = "ReceiverBlue";
public Set<BluetoothDevice> connectedDevices = new HashSet<BluetoothDevice>();
public void onReceive(Context ctx, Intent intent) {
final BluetoothDevice device = intent.getParcelableExtra( BluetoothDevice.EXTRA_DEVICE );
if (BluetoothDevice.ACTION_ACL_CONNECTED.equalsIgnoreCase( action ) ) {
Log.v(CTAG, "We are now connected to " + device.getName() );
if (!connectedDevices.contains(device))
connectedDevices.add(device);
}
if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equalsIgnoreCase( action ) ) {
Log.v(CTAG, "We have just disconnected from " + device.getName() );
connectedDevices.remove(device);
}
}
}
To get currently connected devices:
val adapter = BluetoothAdapter.getDefaultAdapter() ?: return // null if not supported
adapter.getProfileProxy(context, object : BluetoothProfile.ServiceListener {
override fun onServiceDisconnected(p0: Int) {
}
override fun onServiceConnected(profile: Int, profileProxy: BluetoothProfile) {
val connectedDevices = profileProxy.connectedDevices
adapter.closeProfileProxy(profile, profileProxy)
}
}, BluetoothProfile.HEADSET) // or .A2DP, .HEALTH, etc
I think getBondedDevices() will help you :)
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0) {
// Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
Thanks :)
Related
I've connected to Xiaomi air buds via bluetooth settings on my phone.
Then, I tried to use getConnectedDevices(BluetoothProfile.GATT_SERVER) and getConnectedDevices(BluetoothProfile.GATT) methods to get a list of connected devices, but in both cases I got an empty array as a result. If I try to use some other profile in getConnectedDevices() I get an exception that says that I'm using a wrong profile.
How can I correctly get a list of currently connected bluetooth devices to my phone.
code example, in onCreate:
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
List<BluetoothDevice> connectedDevices = mBluetoothManager.getConnectedDevices(BluetoothProfile.GATT_SERVER);
for (BluetoothDevice b :
connectedDevices) {
Log.e(TAG, "onStart: connectedDevice - " + b.toString() );
}
To get a list devices that you connected to ( in the past )
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedList = btAdapter.getBondedDevices();
for (BluetoothDevice pairedDevice : pairedList )
{
Log.d("BT", "pairedDevice.getName(): " + pairedDevice.getName());
Log.d("BT", "pairedDevice.getAddress(): " + pairedDevice.getAddress());
}
To get the device you correctly connected to you will have to use a broadcast receiver like in the following
private final BroadcastReceiver btReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i("Device",device.getName()+ "\n"+ device.getAddress()+"\n"+ device.getBondState());
}
}
};
There's a few more ways to just find out what the state of the connection of the headset as shown here.
if that still not answering your question then I'm sorry I probably misunderstood your question / need.
I have two different bluetooth apps. The first provides a service and listens to commands from the other commander app. I have a GT-I9100T phone and a GT-P5210 tablet. The tablet when acting at the listener works fine and the phone can see the UUID for my app. But when I run the phone as the listener, the UUID of the listener is not listed.
I filter the devices by my application UUID so that I know I am talking only to those devices with my application running.
My listening app looks like this (I get the same result if I use an insecure connection as well):
private final UUID GUID = UUID.fromString("3DEF793A-FA94-4478-AE56-108854B1EF4B");
// other stuff....
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(APP_NAME, GUID);
My commander app MainActivity looks likes this:
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
Log.i(TAG,"Action received: "+action);
if(action.equals(BluetoothDevice.ACTION_UUID)) {
BluetoothDevice btd = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i(TAG,"Received uuids for "+btd.getName());
Parcelable[] uuidExtra = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
StringBuilder sb = new StringBuilder();
List<String> uuids = new ArrayList<String>(uuidExtra.length);
if(uuidExtra != null) {
for (int i = 0; i < uuidExtra.length; i++) {
sb.append(uuidExtra[i].toString()).append(',');
uuids.add(uuidExtra[i].toString());
}
}
Log.i(TAG,"ACTION_UUID received for "+btd.getName()+" uuids: "+sb.toString());
ListContent.addItemWithUUIDs(btd, uuids);
}
}
}
My list content (I am using the master/detail template):
public static synchronized void addItem(BluetoothItem item) {
BluetoothDevice btd = item.mBluetoothDevice;
Log.i(TAG,"Attempting to add "+item.mBluetoothDevice.getName());
if(ITEMS.contains(item)) {
Log.i(TAG,item.mBluetoothDevice.getName()+" already in list");
return;
}
// Do we know this device?
Parcelable[] uuids = btd.getUuids();
Set<String> setUUIDs = new HashSet<String>();
StringBuilder sb = new StringBuilder();
if(uuids != null) {
for (Parcelable parcelable : uuids) {
sb.append(parcelable.toString()).append(',');
setUUIDs.add(parcelable.toString());
}
}
Log.v(TAG,"Device has uuids: "+sb.toString());
if ((btd.getUuids() != null && setUUIDs.contains(BluetoothItem.GUID.toLowerCase()))){
Log.i(TAG, "Found app device: " + btd.getName());
addItem(btd);
} else {
// If we don't know this device, perform sdp fetch of uuids
Log.i(TAG,"Requesting fresh UUIDs for: "+btd.getName());
// this is flushed when discovering finishes
CANDIDATES.add(btd);
}
}
public static synchronized void addItemWithUUIDs(BluetoothDevice btd, List<String> uuids) {
Log.i(TAG,"Attempting to add with uuids"+btd.getName()+" uuids: "+btd.getUuids());
if (uuids.contains(BluetoothItem.GUID)) {
Log.i(TAG, "Found app device: " + btd.getName());
addItem(btd);
} else {
Log.i(TAG, "Ignoring device " + btd.getName() + " without app guid");
}
}
When discovery is finished, this happens:
for (BluetoothDevice i : ListContent.CANDIDATES) {
Log.i(TAG,"Fetching UUIDs for "+i.getName());
i.fetchUuidsWithSdp();
}
ListContent.CANDIDATES.clear();
The logcat output when using the tablet as the commander and phone as listener:
DeviceListActivity(29524): Received uuids for GT-I9100T
DeviceListActivity(29524): ACTION_UUID received for GT-I9100T uuids:
0000110a-0000-1000-8000-00805f9b34fb,
00001105-0000-1000-8000-00805f9b34fb,
00001116-0000-1000-8000-00805f9b34fb,
0000112d-0000-1000-8000-00805f9b34fb,
0000112f-0000-1000-8000-00805f9b34fb,
00001112-0000-1000-8000-00805f9b34fb,
0000111f-0000-1000-8000-00805f9b34fb,
00001132-0000-1000-8000-00805f9b34fb,
I get the correct output with phone as commander and tablet as listener:
DeviceListActivity(23121): Received uuids for GT-P5210
DeviceListActivity(23121): ACTION_UUID received for GT-P5210 uuids:
00001105-0000-1000-8000-00805f9b34fb,
0000110a-0000-1000-8000-00805f9b34fb,
0000110c-0000-1000-8000-00805f9b34fb,
00001112-0000-1000-8000-00805f9b34fb,
00001115-0000-1000-8000-00805f9b34fb,
0000111f-0000-1000-8000-00805f9b34fb,
00001200-0000-1000-8000-00805f9b34fb,
3def793a-fa94-4478-ae56-108854b1ef4b,
As you can see, the GUID for my app is listed as the last item. I've tried making the devices discoverable and bonding and unbonding, but the GUID for my app is never returned for the phone. I have other non-Android devices that also use this GUID and they are discovered normally as well.
The phone is running 4.1.2 and the tablet is 4.2.2
I can list out bluetoothdevices available, but I am not getting the server bluetoothdevice's UUID.
my purpose is to list out number of bluetooth server (another android device/s) available. I am not even sure how can I recognize my server device/s from all the bluetoothdevices available.
For the first mensioned issue, I used fetchUuidsWithSdp() also, but I am getting nullvalue in the UUID broadcast receiver. Somebody please help,
Thanks in advance.
bluetooth = BluetoothAdapter.getDefaultAdapter();
if(bluetooth != null)
{
String status;
if (bluetooth.isEnabled()) {
String mydeviceaddress = bluetooth.getAddress();
String mydevicename = bluetooth.getName();
status = mydevicename + " : " + mydeviceaddress;
bluetooth.startDiscovery();
}
else
{
status = "Bluetooth is not Enabled.";
}
}
And in Broadcast Receiver
public class Receiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
if (BluetoothDevice.ACTION_FOUND.equals(intent.getAction()))
{
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String uuid = intent.getStringExtra(BluetoothDevice.EXTRA);
}
}
I can't figure out how to get my bonded devices on a list through this code :
bt_scan.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0) {
// Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
}});}
I don't know how to get it in a text view or a list view one the same layout or even in another if it's possible.
I'd like to make a connection to one of the found devices but that's a whole other story.
(Here is my full code if it helps : http://pastie.org/4582924)
Thanks a lot !
Yes, I agree with Vishwa, the Bluetooth Chat Application is very helpful, I have done same(like yours) kind of development, here is my code,
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="#+id/title_new_devices"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:background="#666" android:textColor="#fff"
android:paddingLeft="5dp" />
<ListView android:id="#+id/new_devices" android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Activity Class
private static BluetoothAdapter mBtAdapter;
private static ArrayAdapter<String> mNewDevicesArrayAdapter;
private static ArrayList<String> nameList = null;
private static ArrayList<String> macList = null;
private static ListView newDevicesListView = null;
// Register for broadcasts when a device is discovered
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(mReceiver, filter);
// Register for broadcasts when discovery has finished
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(mReceiver, filter);
filter = new IntentFilter( BluetoothAdapter.ACTION_DISCOVERY_STARTED );
this.registerReceiver( mReceiver, filter );
// Get the local Bluetooth adapter
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
BroadCastReceiver Class
private final BroadcastReceiver mReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
try
{
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);
String deviceName = device.getName();
String deviceAddress = device.getAddress();
if ( !nameList.contains( deviceName.trim() + " " + deviceAddress.trim() ) )
{
nameList.add( deviceName.trim() + " " + deviceAddress.trim() );
macList.add( deviceAddress.trim() + "&" + ConstantCodes.TIME + ConstantCodes.EQUALS + DateUtility.getDateTime() );
}
// System.out.println ( device.getName() );
mNewDevicesArrayAdapter.notifyDataSetChanged();
}
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
{
mNewDevicesArrayAdapter.notifyDataSetChanged();
}
else if ( BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals( action ) )
{
// nameList.clear();
}
}
catch ( Exception e )
{
System.out.println ( "Broadcast Error : " + e.toString() );
}
}
};
The code will search for the active bluetooth device and display it in the listView.
Check out the Bluetooth Chat application provided in the Android SDK, it provides a clean way of displaying the phones you are currently paired with.
It also provides a BluetoothChatService class that you can easily adapt to connect found devices.
How can I list all connected bluetooth devices on android ?
thanks!
public void checkConnected()
{
// true == headset connected && connected headset is support hands free
int state = BluetoothAdapter.getDefaultAdapter().getProfileConnectionState(BluetoothProfile.HEADSET);
if (state != BluetoothProfile.STATE_CONNECTED)
return;
try
{
BluetoothAdapter.getDefaultAdapter().getProfileProxy(_context, serviceListener, BluetoothProfile.HEADSET);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private ServiceListener serviceListener = new ServiceListener()
{
#Override
public void onServiceDisconnected(int profile)
{
}
#Override
public void onServiceConnected(int profile, BluetoothProfile proxy)
{
for (BluetoothDevice device : proxy.getConnectedDevices())
{
Log.i("onServiceConnected", "|" + device.getName() + " | " + device.getAddress() + " | " + proxy.getConnectionState(device) + "(connected = "
+ BluetoothProfile.STATE_CONNECTED + ")");
}
BluetoothAdapter.getDefaultAdapter().closeProfileProxy(profile, proxy);
}
};
As of API 14 (Ice Cream), Android has a some new BluetoothAdapter methods including:
public int getProfileConnectionState (int profile)
where profile is one of HEALTH, HEADSET, A2DP
Check response, if it's not STATE_DISCONNECTED you know you have a live connection.
Here is code example that will work on any API device:
BluetoothAdapter mAdapter;
/**
* Check if a headset type device is currently connected.
*
* Always returns false prior to API 14
*
* #return true if connected
*/
public boolean isVoiceConnected() {
boolean retval = false;
try {
Method method = mAdapter.getClass().getMethod("getProfileConnectionState", int.class);
// retval = mAdapter.getProfileConnectionState(android.bluetooth.BluetoothProfile.HEADSET) != android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
retval = (Integer)method.invoke(mAdapter, 1) != 0;
} catch (Exception exc) {
// nothing to do
}
return retval;
}
First you need to retrieve the BluetoothAdapter:
final BluetoothAdapter btAdapter =
BluetoothAdapter.getDefaultAdapter();
Second you need to make sure Bluetooth is available and turned on :
if (btAdapter != null && btAdapter.isEnabled()) // null means no
Bluetooth!
If the Bluetooth is not turned out you can either use btAdapter.enable() which is not recommended in the documentation or ask the user to do it : Programmatically enabling bluetooth on Android
Third you need to define an array of states (to filter out
unconnected devices):
final int[] states = new int[] {BluetoothProfile.STATE_CONNECTED,
BluetoothProfile.STATE_CONNECTING};
Fourth, you create a BluetoothProfile.ServiceListener which
contains two callbacks triggered when a service is connected and
disconnected :
final BluetoothProfile.ServiceListener listener = new BluetoothProfile.ServiceListener() {
#Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
}
#Override
public void onServiceDisconnected(int profile) {
}
};
Now since you have to repeat the querying process for all available Bluetooth Profiles in the Android SDK (A2Dp, GATT, GATT_SERVER, Handset, Health, SAP) you should proceed as follow :
In onServiceConnected, place a condition that check what is the current profile so that we add the found devices into the correct collection and we use : proxy.getDevicesMatchingConnectionStates(states) to filter out unconnected devices:
switch (profile) {
case BluetoothProfile.A2DP:
ad2dpDevices.addAll(proxy.getDevicesMatchingConnectionStates(states));
break;
case BluetoothProfile.GATT: // NOTE ! Requires SDK 18 !
gattDevices.addAll(proxy.getDevicesMatchingConnectionStates(states));
break;
case BluetoothProfile.GATT_SERVER: // NOTE ! Requires SDK 18 !
gattServerDevices.addAll(proxy.getDevicesMatchingConnectionStates(states));
break;
case BluetoothProfile.HEADSET:
headsetDevices.addAll(proxy.getDevicesMatchingConnectionStates(states));
break;
case BluetoothProfile.HEALTH: // NOTE ! Requires SDK 14 !
healthDevices.addAll(proxy.getDevicesMatchingConnectionStates(states));
break;
case BluetoothProfile.SAP: // NOTE ! Requires SDK 23 !
sapDevices.addAll(proxy.getDevicesMatchingConnectionStates(states));
break;
}
And finally, the last thing to do is start the querying process :
btAdapter.getProfileProxy(yourContext, listener, BluetoothProfile.A2DP);
btAdapter.getProfileProxy(yourContext, listener, BluetoothProfile.GATT); // NOTE ! Requires SDK 18 !
btAdapter.getProfileProxy(yourContext, listener, BluetoothProfile.GATT_SERVER); // NOTE ! Requires SDK 18 !
btAdapter.getProfileProxy(yourContext, listener, BluetoothProfile.HEADSET);
btAdapter.getProfileProxy(yourContext, listener, BluetoothProfile.HEALTH); // NOTE ! Requires SDK 14 !
btAdapter.getProfileProxy(yourContext, listener, BluetoothProfile.SAP); // NOTE ! Requires SDK 23 !
source: https://stackoverflow.com/a/34790442/2715054
So you get the list of paired devices.
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevicesList = btAdapter.getBondedDevices();
for (BluetoothDevice pairedDevice : pairedDevicesList) {
Log.d("BT", "pairedDevice.getName(): " + pairedDevice.getName());
Log.d("BT", "pairedDevice.getAddress(): " + pairedDevice.getAddress());
saveValuePreference(getApplicationContext(), pairedDevice.getName(), pairedDevice.getAddress());
}
Android system doesn't let you query for all "currently" connected devices. It however, you can query for paired devices. You will need to use a broadcast receiver to listen to ACTION_ACL_{CONNECTED|DISCONNECTED} events along with STATE_BONDED event to update your application states to track what's currently connected.
I found a solution and it works on android 10
Kotlin
private val serviceListener: ServiceListener = object : ServiceListener {
var name: String? = null
var address: String? = null
var threadName: String? = null
override fun onServiceDisconnected(profile: Int) {}
override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
for (device in proxy.connectedDevices) {
name = device.name
address = device.address
threadName = Thread.currentThread().name
Toast.makeText(
this#MainActivity,
"$name $address$threadName",
Toast.LENGTH_SHORT
).show()
Log.i(
"onServiceConnected",
"|" + device.name + " | " + device.address + " | " + proxy.getConnectionState(
device
) + "(connected = "
+ BluetoothProfile.STATE_CONNECTED + ")"
)
}
BluetoothAdapter.getDefaultAdapter().closeProfileProxy(profile, proxy)
}
}
Call this method in main thread
BluetoothAdapter.getDefaultAdapter()
.getProfileProxy(this, serviceListener, BluetoothProfile.HEADSET)
Java
original code
Please analyze this class online.
Here you will find how to discover all connected (paired) Bluetooth devices.
Well here are the steps:
First, you start intent to discover devices
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
Register a broadcast reciver for it:
registerReceiver(mReceiver, filter);
On the definition of mReceiver:
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
arrayadapter.add(device.getName())//arrayadapter is of type ArrayAdapter<String>
lv.setAdapter(arrayadapter); //lv is the list view
arrayadapter.notifyDataSetChanged();
}
}
and the list will be automatically populated on new device discovery.