10

I have my phone connected to a Bluetooth speaker and the headphones plugged in. Now I'd like to play audio through the Bluetooth speaker. When I set the audio stream to AudioManager.STREAM_MUSIC it just plays over the headphones.

It doesn't matter if it plays on the headphones as well but I need it to play on the Bluetooth speaker.

How is this possible? The app SoundAbout manages to do that so there must be a way.

EDIT: When I plug in the headphones and only afterwards connect to the Bluetooth speakers all audio plays through the Bluetooth speakers which I want. But I can't expect the user to find that out and before having to show them a complicated message I'd rather find out a way to make the sound always play through BT speakers when connected to some.

Thanks

(Note this is not the same question as this: How to Play audio through speaker even when headset is plugged in? I want it to play on Bluetooth speakers, not on the integrated speaker of the phone.)

Community
  • 1
  • 1
DominicM
  • 2,186
  • 5
  • 24
  • 42
  • i don't think this is possible ,because android can give only one way output at a time.!! And if in case you find something ping me up..! – cpt. Sparrow Mar 01 '17 at 11:18
  • I only need it on the Bluetooth speaker, that would be one way. But sometimes it actually does work two way e.g. when you set the stream AudioManager.STREAM_RING and have a bluetooth speaker connected the audio plays over the phone's speaker AND over the bluetooth speaker (but when you plug in a headphone it doesn't play over the bluetooth speaker anymore, which i need) – DominicM Mar 01 '17 at 11:48
  • A very basic question: why can't you use audiomanager apis to route the audio through bt speaker? Is it not working? I thought it was straightforward to force audio through bt using startBluetoothSco(). I haven't tried this but checking if there was an issue using this. – manishg Mar 03 '17 at 15:49

5 Answers5

4

Solution

Suppose you already tested STREAM_RING on your new instance of media player and not directly setting stream type, and it didn't work out, You need a correct profile for your bluetooth device.

Take a look at this article Read the "Implementing HAL" section, there is alot of source for different profile that you may be able to use.

There is also an easy solution which is to change your device profile to HEADSET in your getServiceConnected() method, it will turn into a Stay connected device but the output will become mono! As I recall, Which is a shame for speakers, A2DP also may not be supported in some hardwares and still interrupted by wire headsets.

I suggest to create a new profile and use it, a little bit tricky working with HAL but will worth it,

Sorry that I can not provide a source code for you at the moment.

Iman Nia
  • 2,255
  • 2
  • 15
  • 35
  • @Imzich I have not written any code for android for couple of years, but I will try to provide a sample soon. – Iman Nia Mar 03 '17 at 15:56
  • With STREAM_RING the sound plays through the Bluetooth speaker but also through the phone's internal speakers, which I don't really want. I haven't actually written any bluetooth code because I want the user to be able to connect to BT himself through the OS. And the audio does play through BT when I don't have headphones plugged in, so Buetooth output works, that's not the problem. Or have I misunderstood something? – DominicM Mar 06 '17 at 08:17
  • Note the additional information in bold text I have added to the post – DominicM Mar 06 '17 at 08:24
  • @DominicM I think no body may want to play audio on BT when connected a headphone, your code is doing fine and the user expect the mechanic, but if you insist to do so , you need to build your own profile. Thats all, hope it help :) – Iman Nia Mar 10 '17 at 00:35
  • how to solve this problem for API < 24? (my started from API 16) – Georgiy Chebotarev Nov 12 '18 at 12:24
2

If you have your routing logic within your application then based on that you can decide on which output the audio to be played.

I have a test app written for the exact purpose. My Github Link

You can also route audio as you want based on a requirement.You can refer this github link for routing

Saurav
  • 560
  • 4
  • 17
1

Bluetooth connection may work with below state is true . After receive BluetoothA2dp.STATE_CONNECTED, you can play music as normal.

Java Code Examples for android.bluetooth.BluetoothA2dp.STATE_CONNECTED

public BluetoothHandsfree(Context context, CallManager cm) {
    mCM = cm;
    mContext = context;
    BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
    boolean bluetoothCapable = (adapter != null);
    mHeadset = null;  // nothing connected yet
    mA2dp = new BluetoothA2dp(mContext);
    mA2dpState = BluetoothA2dp.STATE_DISCONNECTED;
    mA2dpDevice = null;
    mA2dpSuspended = false;

    mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    mStartCallWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                                                   TAG + ":StartCall");
    mStartCallWakeLock.setReferenceCounted(false);
    mStartVoiceRecognitionWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                                                   TAG + ":VoiceRecognition");
    mStartVoiceRecognitionWakeLock.setReferenceCounted(false);

    mLocalBrsf = BRSF_AG_THREE_WAY_CALLING |
                 BRSF_AG_EC_NR |
                 BRSF_AG_REJECT_CALL |
                 BRSF_AG_ENHANCED_CALL_STATUS;

    if (sVoiceCommandIntent == null) {
        sVoiceCommandIntent = new Intent(Intent.ACTION_VOICE_COMMAND);
        sVoiceCommandIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    }
    if (mContext.getPackageManager().resolveActivity(sVoiceCommandIntent, 0) != null &&
            BluetoothHeadset.isBluetoothVoiceDialingEnabled(mContext)) {
        mLocalBrsf |= BRSF_AG_VOICE_RECOG;
    }

    mBluetoothPhoneState = new BluetoothPhoneState();
    mUserWantsAudio = true;
    mPhonebook = new BluetoothAtPhonebook(mContext, this);
    mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    cdmaSetSecondCallState(false);

    if (bluetoothCapable) {
        resetAtState();
    }

}

please find below links : with sample codes it may help you.

Java Code Examples for android.bluetooth.BluetoothHeadset

Programmatically connect to paired Bluetooth speaker and play audio

Community
  • 1
  • 1
Chetan Joshi
  • 5,582
  • 4
  • 30
  • 43
0

You need to instantiate a new object of class MediaPlayer and use the following method on it

 amediaplayer.setAudioStreamType(AudioManager.STREAM_RING)

Do not forget to check authorization to use bluetooth, you are unable to send anything to speaker via bluetooth without user privilege as you know.

Rassam
  • 30
  • 8
  • 1
    With STREAM_RING the audio plays on the bluetooth speaker AND on the internal speakers of the phone. Bluetooth output does work with STREAM_MUSIC so that's not the problem but with plugged in headphones it plays through the headphones rather than the bluetooth speaker... – DominicM Mar 06 '17 at 08:19
0

Audiomanager overrides and routes audio to the latest connected device(either wired headset or bluetooth headset). In android, we do not have any option to override this setting unless it is a system app and route the audio wherever we wish to route. However, you can use reflection apis and override this setting. Audiomanager suspends bluetooth connection route(if already connected)if wired headset is connected and vice versa. You can look at the code here.

Hence using reflection apis you can toggle bluetooth audio route by invoking this method.

siva
  • 1,850
  • 13
  • 14