user3389247
user3389247

Reputation: 271

Programmatically connect to bluetooth headset from android app

How to connect to bluetooth headset from my android app? I have found lots of tutorials on discovering bluetooth devices and pairing and very few on connecting.

Upvotes: 8

Views: 18936

Answers (1)

Mo Adel
Mo Adel

Reputation: 1146

First of All, you need to make sure Bluetooth is Enabled then Search for Unpaired Devices, Then Using Device Address, You pair the Device.

After Successful Pairing, you will need to connect to the device and Also HSP or HFP profiles. Note without HSP(Headset Profile) or HFP(Hands-Free Profile) you won't be able to connect and stream calls to your Headset or Speaker.

I laid down the steps for you can easily find more details by googling each step. Hopefully, this helps you.

UPDATE

I will try and help you a bit more : you have to add a new package under the "src" folder with name: android.bluetooth then create IBluetoothHeadset.aidl

with the following code:

package android.bluetooth;

import android.bluetooth.BluetoothDevice;
interface IBluetoothHeadset {

// Public API
boolean connect(in BluetoothDevice device); //Api 11 and above
boolean connectHeadset(in BluetoothDevice device); // Below Api 11

boolean disconnect(in BluetoothDevice device);
boolean disconnectHeadset(in BluetoothDevice device);
    
List<BluetoothDevice> getConnectedDevices();
List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
int getConnectionState(in BluetoothDevice device);
int getState(in BluetoothDevice device);
boolean setPriority(in BluetoothDevice device, int priority);
int getPriority(in BluetoothDevice device);
boolean startVoiceRecognition(in BluetoothDevice device);
boolean stopVoiceRecognition(in BluetoothDevice device);
boolean isAudioConnected(in BluetoothDevice device);
boolean sendVendorSpecificResultCode(in BluetoothDevice device,
                                     in String command,
                                     in String arg);

// APIs that can be made public in future
int getBatteryUsageHint(in BluetoothDevice device);

// Internal functions, not be made public
boolean acceptIncomingConnect(in BluetoothDevice device);
boolean rejectIncomingConnect(in BluetoothDevice device);
int getAudioState(in BluetoothDevice device);

boolean isAudioOn();
boolean connectAudio();
boolean disconnectAudio();
boolean startScoUsingVirtualVoiceCall(in BluetoothDevice device);
boolean stopScoUsingVirtualVoiceCall(in BluetoothDevice device);
void phoneStateChanged(int numActive, int numHeld, int callState, String number, int type);
void clccResponse(int index, int direction, int status, int mode, boolean mpty,
                  String number, int type);
}

Then in your activity

     BluetoothDevice DeviceToConnect;
     IBluetoothHeadset ibth; 
     //IBluetoothHeadset instance used to connect and disconnect headset afterwards

     // Create and Register BroadCastListener for Action "HEADSET_INTERFACE_CONNECTED"
     // In Broadcast your code has to be something like that
     // if(ibth != null) ibth.connect(DeviceToConnect);

     
     //Then After Pairing DeviceToConnect;
     Intent i = new Intent(IBluetoothHeadset.class.getName());

    if (bindService(i, HSPConnection, Context.BIND_AUTO_CREATE)) {

    } else {
       Log.e("HSP FAILED", "Could not bind to Bluetooth HFP Service");
   }

     
      //Method for bind
  public static ServiceConnection HSPConnection= new ServiceConnection() {
        
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            ibth = IBluetoothHeadset.Stub.asInterface(service);
            //ibth instance used to connect and disconnect headset afterwards
            Intent intent = new Intent();
            intent.setAction("HEADSET_INTERFACE_CONNECTED");
            //same as the one we register earlier for broadcastreciever
                            ctx.sendBroadcast(intent);
            //ctx is Instance of Context
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            ibth=null;
        }

    };

UPDATE 2:

<intent-filter> 
  <action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
  <action android:name="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED" />
  <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
</intent-filter>

These are the filters you have to add to your broad cast receiver.

ACL_CONNECTED signals when bluetooth is connected and ACL_DISCONNECTED signals bluetooth disconnection

For specific device you have to check intents/context in broadcast receiver

So your new Receiver including the previous will look something like that:

 BroadcastReceiver bcr = 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 (BluetoothAdapter.ACTION_ACL_CONNECTED.equals(action)) {
           //Device is now connected
        }
        else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
            //Done searching
        }
        else if (BluetoothAdapter.ACTION_ACL_DISCONNECT_REQUESTED.equals(action)) {
           //Device is about to disconnect
        }
        else if (BluetoothAdapter.ACTION_ACL_DISCONNECTED.equals(action)) {
           //Device has disconnected add whatever way u want to be notified here
           //e.g music-vibration-screen light
        }else if("HEADSET_INTERFACE_CONNECTED".equals(action){
           if(ibth != null) ibth.connect(DeviceToConnect);
        }
    }
};

I forgot to add that you need these 2 permissions in Manifest:

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />

Upvotes: 19

Related Questions