list connected bluetooth devices?
This works, but it’s more like polling. Is there a way to have a nice callback of when the list changes? Using BluetoothDevice.ACTION_ACL_CONNECTED, it’s not quite the same as it’s about pairing/bonding, and it’s not reliable either (doesn’t say when it finished bonding) .
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; >
final BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
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
- 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:
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 !
Определение подключенности Bluetooth под Android
Итак, передо мной возникла задача — программно определить подключенно ли какое-то из сопряженных устройств в данный момент к моему телефону посредством Bluetooth. Долго и безуспешно выискивал в сети какое-либо готовое решение по этому поводу, однако удалость найти лишь только указание на то, что есть возможность отслеживания события подключения по Bluetooth. Но ведь программа может быть запущена уже после события, следовательно, это мне не подошло.
Собственно после этого (и листания разделов посвященных Bluetooth в официальной документации Android) и пришла мысль попробовать соединяться с каждым сопряженным устройством, а далее смотреть на успех операции: если успешно — значит устройство в зоне покрытия и подключено. Затея оказалась успешной.
Однако, на пути к ее реализации ожидал еще подвох:
BluetoothSocket bs = device.createRfcommSocketToServiceRecord(MY_UUID); bs.connect();
Этот код создания клиентского подключения никак не хотел выполняться, всегда возвращая ошибку «Service discovery failed». Снова поиск, чтение и выявление факта массы жалоб на такую же проблему. Советы же по решению данной проблемы сводились к одному: предложению различных значений для MY_UUID. Я перепробовал N-ное количество различных UUID из этих советов, но ни с одним соединение между Windows Mobile и Android получить не удалось. Интересный момент: при попытке соединения у «спящего» WM-коммуникатора загорался дисплей. То есть соединение все же инициализируется, но по каким-то причинам не устанавливается. Решение нашлось у соотечественника:
Method m = device.getClass().getMethod("createRfcommSocket",new Class[] < int.class >); socket = (BluetoothSocket)m.invoke(device, Integer.valueOf(1));
И данный способ действительно работает безотказно.
Общий же код проверки Bluetooth’а на подключенность выглядит примерно так:
boolean checkConnected() < BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); boolean connected = false; for (BluetoothDevice device : mBluetoothAdapter.getBondedDevices()) < try < try < Method m = device.getClass().getMethod("createRfcommSocket",new Class[] < int.class >); try < BluetoothSocket bs = (BluetoothSocket) m.invoke(device,Integer.valueOf(1)); bs.connect(); connected = true; Log.d(TAG, device.getName() + " - connected"); break; >catch (IOException e) < Log.e(TAG, "IOException: "+e.getLocalizedMessage()); Log.d(TAG, device.getName() + " - not connected"); >> catch (IllegalArgumentException e) < Log.e(TAG, "IllegalArgumentException: "+e.getLocalizedMessage()); >catch (IllegalAccessException e) < Log.e(TAG, "IllegalAccessException: "+e.getLocalizedMessage()); >catch (InvocationTargetException e) < Log.e(TAG, "InvocationTargetException: "+e.getLocalizedMessage()); >> catch (SecurityException e) < Log.e(TAG, "SecurityException: "+e.getLocalizedMessage()); >catch (NoSuchMethodException e) < Log.e(TAG, "NoSuchMethodException: "+e.getLocalizedMessage()); >> return connected; >
Конечно, работает код не молниеносно. Но тем не менее, код работает и функцию свою выполняет, тем более, что других решений мне найти не удалось. В связи с тем, что опыт работы в Андроид у меня не такой большой, возможно, в коде есть что еще подправить или существует какое-то другое решение. Но это уже подскажут знатоки.
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?
5 Answers 5
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; Lista2dpConnectedDevices = 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).
Android bluetooth get connected devices
How can I get a list of all connected bluetooth devices for Android regardless of profile? Alternatively, I see that you can get all connected devices for a specific profile via BluetoothManager.getConnectedDevices. And I guess I could see which devices are connected by listening for connections/disconnections via ACTION_ACL_CONNECTED/ACTION_ACL_DISCONNECTED. seems error prone. But I’m wondering if there’s a simpler way to get the list of all connected bluetooth devices.
you’re right in that just listening to acl connected / disconnect is problematic because it can occur while your app is not running or listening for the broadcasts
3 Answers 3
To see a complete list, this is a 2-step operation:
To get a list of, and iterate, the currently paired devices:
Set pairedDevices = BluetoothAdapter.getDefaultAdapter().getBondedDevices(); if (pairedDevices.size() > 0) < for (BluetoothDevice d: pairedDevices) < String deviceName = d.getName(); String macAddress = d.getAddress(); Log.i(LOGTAG, "paired device: " + deviceName + " at " + macAddress); // do what you need/want this these list items >>
Discovery is a little bit more of a complex operation. To do this, you’ll need to tell the BluetoothAdapter to start scanning/discovering. As it finds things, it sends out Intents that you’ll need to receive with a BroadcastReceiver.
First, we’ll set up the receiver:
private void setupBluetoothReceiver() < BroadcastRecevier btReceiver = new BroadcastReciver() < @Override public void onReceive(Context context, Intent intent) < handleBtEvent(context, intent); >>; IntentFilter eventFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND); // this is not strictly necessary, but you may wish // to know when the discovery cycle is done as well eventFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); myContext.registerReceiver(btReceiver, eventFilter); > private void handleBtEvent(Context context, Intent intent) < String action = intent.getAction(); Log.d(LOGTAG, "action received: " + action); if (BluetoothDevice.ACTION_FOUND.equals(action)) < BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); Log.i(LOGTAG, "found device: " + device.getName()); >else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) < Log.d(LOGTAG, "discovery complete"); >>
Now all that is left is to tell the BluetoothAdapter to start scanning:
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); // if already scanning . cancel if (btAdapter.isDiscovering()) < btAdapter.cancelDiscovery(); >btAdapter.startDiscovery();
How to get name of the connected Bluetooth device on android
I can get information about the device that is previously paired and trying to make a connection or a device trying to pair to the device. what I want is the name or the connection state of the currently paired and connected device.
2 Answers 2
String name; String address; String threadName; public void checkConnected() < BluetoothAdapter.getDefaultAdapter().getProfileProxy(this, serviceListener, BluetoothProfile.HEADSET); >private BluetoothProfile.ServiceListener serviceListener = new BluetoothProfile.ServiceListener() < @Override public void onServiceDisconnected(int profile) < >@Override public void onServiceConnected(int profile, BluetoothProfile proxy) < for (BluetoothDevice device : proxy.getConnectedDevices()) < name = device.getName(); address = device.getAddress(); threadName = Thread.currentThread().getName(); Toast.makeText(MainActivity.this, name+" " + address+ threadName, Toast.LENGTH_SHORT).show(); txtName.setText(name + " " + address); Log.i("onServiceConnected", "|" + device.getName() + " | " + device.getAddress() + " | " + proxy.getConnectionState(device) + "(connected = " + BluetoothProfile.STATE_CONNECTED + ")"); >BluetoothAdapter.getDefaultAdapter().closeProfileProxy(profile, proxy); > >;
BluetoothServerSocket bluetoothServerSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord("abc", uuid); BluetoothSocket bluetoothSocket = bluetoothServerSocket.accept(); BluetoothDevice device = bluetoothSocket.getRemoteDevice(); String deviceName = device.getName();
looks like the code stock when it get to this line BluetoothSocket bluetoothSocket = bluetoothServerSocket.accept();
Have you checked the documentation? developer.android.com/guide/topics/connectivity/… Check out the sections «Querying paired devices» and «Discovering devices». Especially the call to device.getName()
Thanks for your reply. But what I want is to get the connection status of the currently paired and connected Bluetooth device . No the ones that are trying to connect. For that situation I preferred to use broadcast Listers
And about the link you mentioned, BluetoothDevice class doesn’t provide a function to make a query of paired devices connection state