boring91
boring91

Reputation: 1121

Using a Bluetooth Headset as a Mic and Speaker in a Voice Chat App

I have a voice chat app, which works just fine. Currently I'm trying to make the app support bluetooth headsets in case any was connected. There are two cases that I need to handle:

  1. The bluetooth headset is connected before the call starts.
  2. The bluetooth headset connects to the device during the call.

For the first case, the app should automatically starts using the headset as its default input/output audio device. On the other hand, the app, upon headset connection to the device, should switch from the current input/output audio device to the bluetooth headset.

I was able to handle the first case successfully using the following code:

mAudioManager.setMode(0);
mAudioManager.startBluetoothSco();
mAudioManager.setBluetoothScoOn(true);
mAudioManager.setMode(android.media.AudioManager.MODE_IN_CALL);

As for the second case, I created a BroadcastReciever that listens when a bluetooth headset is connected as follows:

mBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
            mAudioManager.setMode(0);
            mAudioManager.startBluetoothSco();
            mAudioManager.setBluetoothScoOn(true);
            mAudioManager.setMode(android.media.AudioManager.MODE_IN_CALL);
        } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
            mAudioManager.setMode(0);
            mAudioManager.startBluetoothSco();
            mAudioManager.setBluetoothScoOn(false);
            mAudioManager.setMode(android.media.AudioManager.MODE_IN_CALL);
        }
    }
};

The BroadcastReciever was able to detect headset connections/disconnections, and the call was directing the sound to the headset rather than the phone's earpiece. The issue is that the app keeps using the device's mic as the input audio device rather than the headset's. After a very long inspection, I realized that when the BroadcastReciever gets a notification that a headset is connected, I need to wait a little bit before calling mAudioManager.startBluetoothSco(); to get the app to use the headset's mic.

The question is, what kind of event should I be listening to, after knowing that the bluetooth headset is connected, so that I can start capturing the voice from the headset's mic?

Upvotes: 2

Views: 1713

Answers (1)

boring91
boring91

Reputation: 1121

It turns out the I shouldn't be listening to BluetoothDevice.ACTION_ACL_CONNECTED, rather the one I should consider is BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED. The BroadcastReciever should be initialized as follows:

mBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
            int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, -1);
            boolean result = state == BluetoothHeadset.STATE_CONNECTED;
            mCallback.onConnected(result);
        }
    }
};

Upvotes: 1

Related Questions