Programmatically connect to paired Bluetooth device
Asked Answered
H

4

57

Is there a way, using the Android SDK, to programmatically connect to an already-paired Bluetooth device?

In other words: I can go into Settings -> Wireless & networks -> Bluetooth settings, and tap the device (listed as "Paired but not connected"), at which point it will connect. I'd like to be able to do this programmatically, but don't see a way to do this.

I see the options to create an RFCOMM socket, and for a SPP device, I'm assuming that'll do the connection part as well, but for an A2DP device, where the actual data transfer will be handled by the OS rather than by my app, I think that's not applicable?

Hanseatic answered 2/3, 2011 at 17:38 Comment(1)
Did you resolve this issue? I'm wanna know, too.Dacy
A
59

Okay, since this was driving me crazy, I did some digging into the source code and I've found a 100% reliable (at least on my Nexus 4, Android 4.3) solution to connect to a paired A2DP device (such as a headset or Bluetooth audio device). I've published a fully working sample project (easily built with Android Studio) that you can find here on Github.

Essentially, what you need to do is:

  • Get an instance of the BluetoothAdapter
  • Using this instance, get a profile proxy for A2DP:

adapter.getProfileProxy (context, listener, BluetoothProfile.A2DP);

where listener is a ServiceListener that will receive a BluetoothProfile in its onServiceConnected() callback (which can be cast to a BluetoothA2dp instance)

  • Use reflection to acquire the connect(BluetoothDevice) method on the proxy:

Method connect = BluetoothA2dp.class.getDeclaredMethod("connect", BluetoothDevice.class);

  • Find your BluetoothDevice:

String deviceName = "My_Device_Name";

BluetoothDevice result = null;

Set<BluetoothDevice> devices = adapter.getBondedDevices();
if (devices != null) {
    for (BluetoothDevice device : devices) {
        if (deviceName.equals(device.getName())) {
            result = device;
            break;
        }
    }
}

  • And invoke the connect() method:

connect.invoke(proxy, result);

Which, at least for me, caused an immediate connection of the device.

Affricative answered 23/8, 2013 at 8:11 Comment(17)
@kcoppock sir please check #26801106 for SPP profilePoetess
@kcoppock: Is it possible to apply it for Handset profile. I tried it to connect with my headset device, however, your project did not workKohima
@user8264: There is also a BluetoothHeadset class as well as a BluetoothProfile.HEADSET constant. The changes to use these should be fairly trivial.Affricative
Yes. This is my project. However, I tried to connect to headset and stream audio from headset device to android phone, I have some problem with echo sound. This is my question. #27777805Kohima
I downloaded the project in GitHub and somehow managed to integrate it into my own code so that now I can divert the phone audio output via bluetooth to my custom audio sink device. However, I do not seem to be able to figure out when the functions in the BluetoothBroadcastReceiver are being called. Are they necessary? When exactly do they get called? (for now, this is how my app works -> discovery -> pairing (for simplicity there are no previously paired devices and only one remote devic e to connect to) -> A2DP channel using BluetoothA2DPRequester -> all audio goes to the remote A2DP sinkBahamas
This should be the accepted answer. Using reflection to force an A2DP connection works fine :) (until Google blocks it..)Stewpan
I have a question about using this from a broadcast receiver. I would like to automatically pair the bluetooth device once bluetooth is turned on. However, Android prohibits broadcast receivers from binding services. So when the BluetoothProfile.ServiceListener gets called, there's an error. Is there anyway to connect in a broadcast receiver? Thanks!Cecilius
@WayWay You could probably start a new IntentService from your BroadcastReceiver (use the provided Context in onReceive to start it) and let that service do the bluetooth service binding.Affricative
@kcoppock with this library could I autoconnect to the nearest/paired device autommatically? I mean if I turn on the Bluetooth it connects autommatically?Chavarria
No, this is specifically used to work around Bluetooth auto-connect not working.Affricative
Can you check this question please? :(Chavarria
It helped me.. +10 for you (Y)Braswell
I an little bit surprised that "connect", "disconnect" for BluetoothHeadset profile is working Great! But "connect" is not working for BluetoothA2DP profile, "disconnect" is workingAfterbrain
This code actually helped me with an issue where cheaper headsets would pair but not connect when I used the createBond method so I had to force the connection this way. Funnily enough expensive headsets like BeatsX and Airpods didn't need to be forced after pairingMilch
Wow thanks! is there a way to now disconnect the device? i know there is a disconnect method, but sometimes doesnt work :(Conurbation
I'm not sure, never tried that route myself. :) I would expect you could use a similar trick to access the disconnect method on the profile, though. That said, expect this solution to stop working, likely in Android Q, as many of these private APIs are becoming restricted.Affricative
@KevinCoppock, you are brilliant! Just now you have saved my time! Thank you!Iodous
A
4

the best way I found to solve my problem was finding out that I can create a button that brings up the Bluetooth Settings screen. I didn't realize you could do this, or I would have from the beginning.

startActivity(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS));
Alina answered 29/8, 2011 at 1:21 Comment(1)
That is not "programmatically" method. Still requires user interaction.Rockhampton
P
3

if the device is already paired , then you can use

if(device.getBondState()==device.BOND_BONDED){

        Log.d(TAG,device.getName());
        //BluetoothSocket mSocket=null;
        try {


            mSocket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            Log.d(TAG,"socket not created");
            e1.printStackTrace();
        }
        try{

            mSocket.connect();

        }
        catch(IOException e){
            try {

                mSocket.close();
                Log.d(TAG,"Cannot connect");
            } catch (IOException e1) {
                Log.d(TAG,"Socket not closed");
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }


        }

for the MY_UUID use

private static final UUID MY_UUID = UUID.fromString("0000110E-0000-1000-8000-00805F9B34FB");

the above code snippet is just to connect your device to an A2DP supported device. I hope it will work.

Phlogistic answered 10/9, 2012 at 11:52 Comment(4)
Will this force connect an a2dp headset?Guanaco
it will only connect to the device that supports A2DP profile, being an insecure socket, it will just connect without asking for pairing(as we want, because your device is already paired).Phlogistic
please change the UUID to "0000110A-0000-1000-8000-00805F9B34FB" or "0000110B-0000-1000-8000-00805F9B34FB".... The above UUID is for AVRCP not for A2DP ,it just slipped out of my mind.Phlogistic
will this code will work to connect any unsecure bluetooth device?Kirima
L
1

I used the code here as a starting point for this functionality in my app: http://developer.android.com/guide/topics/wireless/bluetooth.html#ConnectingDevices

Once the device is paired, the app has no problem connecting the two devices together programmtically.

Lisettelisha answered 2/3, 2011 at 18:23 Comment(3)
Marc: thanks for the reply. That's good for peer-to-peer application connections where it's your app that wants to send data (and hence grabs the BluetoothSocket), but in this case, I just need to establish a connection for A2DP; the actual data stream is handled by the OS.Hanseatic
Ahh, it wasn't clear to me that your other device is not an Android device.Lisettelisha
Have you found solution to connection with other bluetooth device(paired) non android @Hanseatic ?Gesellschaft

© 2022 - 2024 — McMap. All rights reserved.