My use case is I have an app in which a user can press a button and it would toggle between external speaker and the wired headset/bluetooth device. If the user is connected to a wired headset or a bluetooth ear piece device, I want to switch the audio output from that wired headset or bluetooth to the external speaker, and then when they click again, to renable the wired headset/bluetooth audio output.
Does anyone know this can be done in Android 10? I tried the following the example in this post but it doesnt consistently work for bluetooth cases. My code is as followed:
if (shouldEnableExternalSpeaker) {
audioManager.mode = AudioManager.MODE_IN_COMMUNICATION
audioManager.isSpeakerphoneOn = true
if (isBlueToothConnected) {
audioManager.stopBluetoothScoOn()
}
} else {
if (isBlueToothConnected) {
audioManager.startBluetoothSco()
}
audioManager.mode = AudioManager.NORMAL
audioManager.isSpeakerphoneOn = false
}
I also have the necessary permission to the user's audio:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
I think you should split your handling into 3 cases, play sound via:
The resulting code could then loke like this.
if(shouldEnableExternalSpeaker) {
if(isBlueToothConnected) {
// 1. case - bluetooth device
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mAudioManager.startBluetoothSco();
mAudioManager.setBluetoothScoOn(true);
} else {
// 2. case - wired device
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mAudioManager.stopBluetoothSco();
mAudioManager.setBluetoothScoOn(false);
mAudioManager.setSpeakerphoneOn(false);
}
} else {
// 3. case - phone speaker
mAudioManager.setMode(AudioManager.MODE_NORMAL);
mAudioManager.stopBluetoothSco();
mAudioManager.setBluetoothScoOn(false);
mAudioManager.setSpeakerphoneOn(true);
}
Even though I haven't used the AudioManager
recently, this has worked for me in the past.
Lines:
audioManager.isSpeakerphoneOn = true
audioManager.isSpeakerphoneOn = false
will not work. You have to use setMethods:
Case 1 - bluetooth
mAudioManager.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.
mAudioManager.setBluetoothScoOn(true); // set true to use bluetooth SCO for communications; false to not use bluetooth SCO for communications
Case 2 - wired
mAudioManager.stopBluetoothSco(); // stop wanting to send and receive
mAudioManager.setBluetoothScoOn(false); // turn off bluetooth
mAudioManager.setSpeakerphoneOn(false); //set true to turn on speakerphone; false to turn it off
Case 3 - internal speaker
mAudioManager.stopBluetoothSco();
mAudioManager.setBluetoothScoOn(false);
mAudioManager.setSpeakerphoneOn(true); // turn on speaker phone
You can keep things automatically happening as follows:
public class BluetoothReceiver extends BroadcastReceiver {
private AudioManager localAudioManager;
private static final int STATE_DISCONNECTED = 0x00000000;
private static final String EXTRA_STATE = "android.bluetooth.headset.extra.STATE";
private static final String TAG = "BluetoothReceiver";
private static final String ACTION_BT_HEADSET_STATE_CHANGED = "android.bluetooth.headset.action.STATE_CHANGED";
private static final String ACTION_BT_HEADSET_FORCE_ON = "android.bluetooth.headset.action.FORCE_ON";
private static final String ACTION_BT_HEADSET_FORCE_OFF = "android.bluetooth.headset.action.FORCE_OFF";
@Override
public void onReceive(final Context context, final Intent intent) {
Log.i(TAG,"onReceive - BluetoothBroadcast");
localAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
final String action = intent.getAction();
if (action.equals(ACTION_BT_HEADSET_STATE_CHANGED)) {
final int extraData = intent.getIntExtra(EXTRA_STATE, STATE_DISCONNECTED);
if (extraData == STATE_DISCONNECTED) {
//no headset -> going other modes
localAudioManager.setBluetoothScoOn(false);
localAudioManager.stopBluetoothSco();
localAudioManager.setMode(AudioManager.MODE_NORMAL);
Log.i(TAG, "Bluetooth Headset Off " + localAudioManager.getMode());
Log.i(TAG, "A2DP: " + localAudioManager.isBluetoothA2dpOn() + ". SCO: " + localAudioManager.isBluetoothScoAvailableOffCall());
} else {
localAudioManager.setMode(0);
localAudioManager.setBluetoothScoOn(true);
localAudioManager.startBluetoothSco();
localAudioManager.setMode(AudioManager.MODE_IN_CALL);
Log.i(TAG, "Bluetooth Headset On " + localAudioManager.getMode());
Log.i(TAG, "A2DP: " + localAudioManager.isBluetoothA2dpOn() + ". SCO: " + localAudioManager.isBluetoothScoAvailableOffCall());
}
}
if (action.equals(ACTION_BT_HEADSET_FORCE_ON)) {
localAudioManager.setMode(0);
localAudioManager.setBluetoothScoOn(true);
localAudioManager.startBluetoothSco();
localAudioManager.setMode(AudioManager.MODE_IN_CALL);
Log.i(TAG, "Bluetooth Headset On " + localAudioManager.getMode());
Log.i(TAG, "A2DP: " + localAudioManager.isBluetoothA2dpOn() + ". SCO: " + localAudioManager.isBluetoothScoAvailableOffCall());
}
if (action.equals(ACTION_BT_HEADSET_FORCE_OFF)) {
localAudioManager.setBluetoothScoOn(false);
localAudioManager.stopBluetoothSco();
localAudioManager.setMode(AudioManager.MODE_NORMAL);
Log.i(TAG, "Bluetooth Headset Off " + localAudioManager.getMode());
Log.i(TAG, "A2DP: " + localAudioManager.isBluetoothA2dpOn() + ". SCO: " + localAudioManager.isBluetoothScoAvailableOffCall());
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With