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...
Related
what's the benefits of calling startBluetoothSco when android takes care of that on Androids end, and when you connect a BT headset to android the sound automatically passes to android
so why would we want to specify startBluetoothSco anyway?
is it just if we have a dedicated button to move to Bluetooth ? and then when it's pressed we can move to the headset ?
or not all android versions move to the headset automatically?
By default, nothing connects to a BT SCO(hands-free profile) headset automatically. You may be thinking of A2DP (stereo profile), which does get "auto-enabled".
You may also be confused because some headsets have both profiles, and the OS auto-switches to the A2DP one. But if you actually want to use SCO, it always has to be manually connected.
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.
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.
My problem is - how to set up bluetooth incall audio volume.
Since there some apps for this, no one of them works.
Anyway - no app - create one for yourself. I'm very begginer in android development, so i've tried use audioManager.setStreamVolume(), but without any luck - only internal audio has changed after this.
Even playing with startBluetoothSCO() wasn't the answer.
After looking in logcat, how os responds to pressing volume keys, i found out, that after startBluetoothSCO() volume keys in my phone sends AT commands instead of mangling streams (AT+VGM=0...15).
So my code should look something like this:
AudioManager audioManager = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
audioManager.startBluetoothSco();
// send AT commands
audioManager.stopBluetoothSco();
Crawling thru web provide me answer that there's no way to directly access modem (and propably other comm ports) from Android API.
So, maybe someone has any goddamn idea how to prevent resetting BT volume on each connect/disconnect to headset? Using code that i could use by myself, or using some 3-rd party app that is available somewhere.
OS: GB 2.3.4, SGS
Thanks for any ideas.
You can send AT commands via RFCOMM connection. But you must do this before the Android has created Headset/Handsfree Profile connection (Called Phone audio in bluetooth settings menu), or at least disconnect the HSP/HFP then connect via RFCOMM on either of the two (Both HSP and HFP should work with unsolicited +VGS commands), set the volume, and then reconnect.
I'm using my Nexus One with Android 2.2 Froyo in my car dock. For the audio output I'm using a a2dp receiver which is hooked up to my car stereo.
Now, when I put the phone in the car dock it automatically connects to the car dock but not to my a2dp receiver, I have connect it manually in the settings (already paired).
I'm also using a custom app for audio playback. I thougt I maybe could force the a2dp connection to the a2dp receiver. But as far as I know, the default Bluetooth API does not support such a thing.
Is there any Intent for establishing the connection, or any other way? I would also accept an undocumented solution.
I fixed this recently with the app A2DP volume.
My issue was my lg p920 on android 2.3.5 would connect to handsfree and a2dp stereo audio with my Sony car stereo mex bt3950ou (many other brands have the same issue).
Once the car was turned off and back on again ie. in turning the ignition from acc to start, the connection would be lost and only the handsfree would reconnect.
A2DP volume can be configured to force reconnect the stereo audio connection, see instructions on the A2DP volume site.
See your issue with twin BT devices. You can get BT Visor mount systems that do this. The BB version will stream A2DP music from the device AND allow you to take calls. The drawback is it uses FM to get the sound to your headunit so sound quality will be lower than native BT.
The technique is demonstrated in this app: http://code.google.com/p/a2dpvolume/A2DP Volume
Look at service.java and the IADL file.