I need to know from glass, if there is a phone call in process. I can made it easy on android device ... but I have problems with glass, the same code to telephonymanager and so on ... doesn't works on glass.
Any idea how to catch the broadcasting process or PhoneCallManager to know if the phone has is talking?
thanks for advice.
Glass works as a bluetooth headset when making a phone call (see user guide). It is not making the calls itself.
I think you'll have to use the BluetoothHeadset class which will allow you to interact with the Headset bluetooth profile. You can then retrieve the state of the headset connection.
Related
I was doing some research and wanted to know if it's possible to handle calls of my phone from a device (smart watch, bluetooth headset) that is connected to my phone via bluetooth.
I intend it be able to answer calls that come to phone and make calls from my phone when I give the command to the device and I want that device to act like the bluetooth speaker during the call.
I've seen use cases where it is done but have no idea on how it's done or where to start, Any ideas on this? :)
What you are looking for is smartwatch with a speaker/microphone. You should be able to find plenty of them on internet.
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.
What I want to know:
I'm wondering how the android system (like Android smart phone) auto-connects to devices which is paired before.
For example, I pair my bluetooth headset with my android smartphone in the procedure of "turn on scanning/advertising -> click pairing" on day 1. And when I turn on advertising on my headset, it connects automatically on day 2, 3, 4, and so on. The point is, I don't have to make my smartphone scan again to find my (paired) headset.
I can't understand how android system finds that the paired device is turned on. Does the android system scan periodically in background? Even if I don't click "scan" button?
Why I ask:
I want to make my app autoconnect to customized BLE device, after make pairing. I succeed to make pairing(bonding) with createBond() method, but after that, I couldn't find how to make autoconnect. I know I can turn on autoconnect function like this way, connectGatt(XXX, true, XXX), but this autoconnect function doesn't work when the BLE device is disconnected a few days.
So I want to make my app works like android system and Bluetooth headset. But I couldn't find how android bluetooth system works even I dig AOSP codes.
I found many questions (here and here) about problems like mine but there were no answers.
Thanks in advance.
Update:
I found that bt_btif gets activated (with LG smartphone and Nexus 5) when the paired headset is turned on (start advertising). But bt_btif doesn't get activated with my custom BLE device... What can I do?
Executing connectGatt(XXX, true, XXX) is the correct way to go. gatt.connect() also starts an auto connect. Once you execute that, your phone will scan for the device and once it appears it connects to it. The only thing that interrupt this call is either if Bluetooth is turned off on the phone or if your app process is being killed. To avoid your process from being killed, let your app have a foreground service.
One gotcha however, there is a bug in Android which will sometimes make auto connect do a direct connect instead (and cancel after 30 seconds or so). See https://code.google.com/p/android/issues/detail?id=69834. You need to use reflection to avoid this bug.
I think I found a solution.
First, the solution for my question: Android smartphone seems to detect state changes of nearby bluetooth devices from the hardware sides. When the paired bluetooth headset starts to advertise, a callback in HAL (I think) is called.
So I made my app to connectGatt with autoConnection=True to the device that I want, by using MAC address, when the activity is started (in onResume() of MainActivity).
The connection would fail if my BLE peripheral device is not advertising. But the device auto-connects when it starts advertising, because the autoConnection parameter was set to true.
I've done a similar app and i didn't have problem with that. As a last resort for your problem, i would suggest writing the BLE Device Address in a simple DB table and manually connect to it. I've made something like this here
. It is no best practice code, but i hope you can find ideas for you solution.
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...
I can already detect when an Android phone makes or takes a phone call, but I would also like to know if a bluetooth headset is being used for the call and/or if the phone's speaker is being used for the call. I have looked around a bit but I don't see anything that can do this. Is this possible?
I think you can use AudioManager's isBluetoothScoOn(), it should work fine.