Switching Bluetooth SCO (headset) device when multiple are connected - android

I'm working on getting bluetooth working in my app for VoIP calls, and I can get the headset connected and playing correctly.
I'm using a combination of listening for Bluetooth Headset changes as well as using the Bluetooth profile proxy to see which headsets are connected.
When I call get the proxy,
mBluetoothAdapter.getProfileProxy(context, pofileListener, BluetoothProfile.HEADSET)
https://developer.android.google.cn/reference/android/bluetooth/BluetoothAdapter#getProfileProxy(android.content.Context,%20android.bluetooth.BluetoothProfile.ServiceListener,%20int)
I get a list of the currently connected bluetooth headset devices, and it tells me which one is connected to Audio with a boolean flag
https://developer.android.google.cn/reference/android/bluetooth/BluetoothHeadset#isAudioConnected(android.bluetooth.BluetoothDevice)
I can't figure out how to change the audio source though? I want to show these two connected devices in a dialog and let the user choose between them.
I can physically turn one or the other device on/off and the audio transitions smoothly every time, I just want to let the user choose where the audio goes.

Related

Answer VoIP call on bluetooth headset

Overview
I'm currently working on an android app that supports VoIP calls (using webrtc). Everything's working perfectly, but now I'm trying to add support for bluetooth headsets. I want the calls to be answered/hangup automatically (without the user touching the device's screen) if:
The user has a bluetooth headset connected to his device
The Answer/Hangup button was pressed
Problem
I'm still struggling to make this work. I've read all related stack overflow questions (like this and this), but still no luck.
What I've tried:
Obtain the bluetooth profile proxy using bluetoothAdapter.getProfileProxy(context, serviceListener, BluetoothProfile.HEADSET).
On the service listener (a BluetoothProfile.ServiceListener) check if the obtained BluetoothHeadset has a connected bluetooth device. If true, register a BroadcastReceiver with an IntentFilter that has the actions android.intent.action.MEDIA_BUTTON, android.media.ACTION_SCO_AUDIO_STATE_UPDATED and android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED and call audioManager.startBluetoothSco().
I'm only receiving broadcasts for the android.media.ACTION_SCO_AUDIO_STATE_UPDATED action. What's wrong with my approach?
Any help would be appreciated.
I have not developed VoIP apps, so I am not sure about correct sequence of events and control calls in this case. Not sure that this can help, just some notes from Bluetooth point of view. Intents BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED (android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED) are about BluetoothHeadset's RFCOMM connection, it is kept alive if Handsfree/Headset profile is enabled for specific Handsfree unit and Handsfree unit is in use. You need these intents to detect if you need to look after BluetoothHeadset state or not, so you will not receive them during calls.
You can also register a receiver for BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED intents (android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED). In BluetoothHeadset source and accordingly in Android documentation it described as "Audio Connection state of the A2DP profile", but this is wrong. This is state of Handsfree/Headset physical audio SCO connection. This connection is active during voice calls, Bluetooth voice recognition and ringing (if In Band Ringing feature is supported and enabled). I do not remember how BluetoothHeadset audio state concerns AudioManager's SCO state.

How call process works with blue tooth devices?

I tested few things on Android mobiles with bluetooth headset.I have few questions regarding the same.
Device Specifications :
Android 2.3 above
Headset Blue tooth profiles : HFP,A2DP
I accepted a call from accept button from the android mobile and I was able to hear the call from the bluetooth headset.After that I moved android device out of range and accepted the call from android and when the android mobile entered bluetooth range bluetooth headset connected automatically.Is it universal, I mean all the bluetooth headsets support the same or are there any deviations?
I would like to know what will happen when we accept the call from headset or Android mobile.Is it something like Android OS is going to create a call session/audio session and transfer this to headset when accept button is pressed from the headset.If a call is already received and when the headset is in bluetooth range,Android mobile is going to route the volume to headset. In both the cases the same thing happens(just routing the audio).I would like to know the call handling in detail both the cases.Could some one help me on this.
How the call process is different in iOS?
Edit
Is any call session like AVAudoioSession is getting created when we accept a call ?
#jjv360:
"An app can manually assign a route even though a bluetooth headset is connected, in which case it's up to the app to handle what happens when a new route is detected..."
Is it possible to route the call session to headset(from microphone to headset sco) in an iOS app?Could you please give some pointers on this.
On iOS if you connect a bluetooth headset while an audio session is active the current audio app(s) get notified and by default will transfer the session's route to the headset. An app can manually assign a route even though a bluetooth headset is connected, in which case it's up to the app to handle what happens when a new route is detected...
Also, AFAIK the reconnect is attempted by both the device (for a very short time) and the headsets, so it's mainly up to the headset to attempt reconnecting when it goes out of range. Almost all headsets should do this though.
It doesn't matter which button was used to accept the call (on device or on headset), if the bluetooth headset is connected it will be used, unless an app has specified that it doesn't want to use that route.
The call process AFAIK is the same for Android and iOS.
With the protocol used, A2DP is the high-quality protocol used when listening to music. It supports high-quality audio, but is one-way, so only works if the bluetooth headset is not recording from the mic. HFP is used when recording is also needed, but the quality is less. That is why you will notice on iOS if you're listening to music on bluetooth headset and then start a recording app, the sound quality will become worse until you stop the recording...

Can I notify when any bluetooth of paired device is enabled?

Hi I am working with embedded bluetooth device connection with my android application.
My application is installed in Android phone and phone has some paired bluetooth devices, Now I want that if any paired bluetooth device is enabled(starts/turns on) the application should receive notification.
of-course bluetooth will be enabled in phone and bluetooth devices will be within range.
please let me know How this is possible ?
Thanks!
How about using http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#ACTION_CONNECTION_STATE_CHANGED
To check all changed states and then comparing what the new state is:
STATE_DISCONNECTED, STATE_CONNECTING, STATE_CONNECTED etc.
There is nothing automatic that can detect this, you will have to make both your App and the paired device do some work to detect this. TYhere could be 2 options :
Your app could do some periodic device discovery (low frequency - else it will kill the battery) to search for the paired devices in vicinity.
The paired devices on getting enabled / starting on should put itself to be discoverable.
A better way is for the apired device to autimaically initiate a connection once it comes on to the device it was paired with, and typically on most phones by default if Bluetooth is turned on its also scanning for incoming connection , so your app can be ready to accept incoming connections.

Android bluetooth programming: Sending event/data from Bluetooth headset to Android Phone via bluetooth.

As part of one of my course project, i want to initiate/trigger my own android app through the bluetooth headset or any such bluetooth device by pressing the available button on them. I will press any specific button on my bluetooth headset and my application should be able to detect that button press event and start its execution automatically.
Just read http://developer.android.com/guide/topics/connectivity/bluetooth.html. You need to create a listening bluetooth server on you'r phone, read Connecting as a server and Working with Profiles.

Android Bluetooth Headset Transition

How exactly does Android handle the transition to a bluetooth headset when the connection is made? With the default music application, my device stops the audio from coming out the speaker, then routes it to the headphones as soon as a connection is made. When turning off the bluetooth headset, the device immediately detects the lost connection and starts routing through the device speaker again. Is this handled by the Android OS or by the application itself?
I ask because I am working on an app that plays streams off the internet. My app only behaves as described above 50% of the time. Sometimes when connecting the bluetooth headphones the audio does not automatically switch until I stop the output and start it again. The same goes for a disconnection. The device detects that the headphones are gone, but my audio does not automatically return back through the speakers until I restart the stream.

Categories

Resources