The key thing is to call audioManager.startBluetoothSco().
This method can be used by applications wanting to send and received audio to/from a bluetooth SCO headset while the phone is not in call.
This is an asynchronous operation, as such, you can register a BroadcastReceiver
to be notified once audio will start being recorded through the bluetooth headset like so
private BroadcastReceiver mBluetoothScoReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
// Start recording audio
}
}
};
@Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
registerReceiver(mBluetoothScoReceiver, intentFilter);
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.startBluetoothSco();
}
The docs also mention something very important
the application can check the SCO audio state before calling startBluetoothSco() by reading the intent returned by the receiver registration. If the state is already CONNECTED, no state change will be received via the intent after calling startBluetoothSco().
And...
It is however useful to call startBluetoothSco() so that the connection stays active in case the current initiator stops the connection.
This means you do not have to wait for the receiver to be called if the SCO connection is already active. Here is the updated code snippet.
@Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
Intent intent = registerReceiver(mBluetoothScoReceiver, intentFilter);
if (intent == null) {
Log.e(TAG, "Failed to register bluetooth sco receiver...");
return;
}
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
// Start recording
}
// Ensure the SCO audio connection stays active in case the
// current initiator stops it.
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.startBluetoothSco();
}
You should stop the SCO connection if you are not using it.
private void onPause() {
super.onPause();
unregisterReceiver(mBluetoothScoReceiver);
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.stopBluetoothSco();
}
You will also need the following permissions in your AndroidManifest.xml
file
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY"/>