I am able to receive, hangup and dial a number from my headset to android mobile which are connected via bluetooth.
Now, once I receive a in-coming call of mobile in headset, I need to speak with the called person from headset. I need to stream my voice via bluetooth to android mobile. I am searching for this code.
Crawled n number of post but could not get appropriate answer, Currently am using below but its not working...
AudioManager audioManager;
audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
audioManager.startBluetoothSco();
audioManager.setBluetoothScoOn(true);
audioManager.setSpeakerphoneOn(true);
I am not sure after this what line of code I need to write to achieve my requirement
Note: I receive in-coming call by sending mmOutStream.write("ATA\r".getBytes()); this AT command to my Android mobile.
Please correct and guide me to perform audio stream.
You should set speakerphone to false, otherwise your output will be re-directed there. It is enough to do this:
audioManager.setSpeakerphoneOn(false);
audioManager.startBluetoothSco();
audioManager.setBluetoothScoOn(true);
Also, you can optionally set microphone to un-mute state (just in case previous state was muted):
mAudioManager.setMicrophoneMute(false);
Related
I'm looking to pair A2DP stereo sound with the interrupt functionality of AudioManager's MODE_IN_COMMUNICATION. The purpose of this pairing is to insert snippets of custom music into AM/FM broadcasts by using the music as something that "dials" the Android device and stops the AM/FM broadcast.
I have this working decently with SCO using the following code to start the "phone call".
Here is the AudioManager code:
AudioManager localAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
localAudioManager.setMode(0);
localAudioManager.setBluetoothScoOn(true);
localAudioManager.startBluetoothSco();
localAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
Here is the MediaPlayer I'm trying to play:
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioAttributes(new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build());
mediaPlayer.setDataSource("https://wmbr.org/WMBR_Archive_128.m3u");
mediaPlayer.prepare();
mediaPlayer.start();
The audio produced by this code is low-quality and mono as opposed to stereo. I would like to change that.
The issue is that the Android Dev site for startBluetoothSco says:
Even if a SCO connection is established, the following restrictions apply on audio output streams so that they can be routed to SCO headset: - the stream type must be STREAM_VOICE_CALL - the format must be mono - the sampling must be 16kHz or 8kHz
Is there any existing way to combine stereo sound and the interrupt functionality?
Additional context: in this answer it seems that MODE_IN_COMMUNICATION and MODE_IN_CALL use the PHONE routing strategy. He also says
If your BT accessory supports the Hands-free profile it will use a SCO link for the voice audio, and the ACL channel used for A2DP should be closed to avoid interference between the two.
I'm assuming this means my only option is a custom routing strategy, and I'm not sure what that entails.
As we know,we could record voice via Bluetooth headset,we should use SCO link, but when a call coming, the system will lost sco link,so that, I can't get PCM data from SCO link. how to resolve it.
I'd try to this code,but it doesn't work.
AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
am.setMode(AudioManager.MODE_IN_COMMUNICATION);
am.startBluetoothSco();
am.setBluetoothScoOn(true);
when phone is ringing, can i record from SCO?
Android changes audio routing depending on its needs, and when the phone is ringing (and/or when the call is answered) the audio is re-routed to target device (earpiece, headphones, BT, etc..). It's impossible to start a single recording Object and get all the data (the data before, current and future voice during communication), but you have to monitoring the voicecall status (or the current Audio Routing state) and close the previous recording object and then create a new one using different settings.
If you are interested ONLY in your voice while your phone is ringing, you could do it by recording that data using UPLINK as the AudioSource of Recording object.
I am wondering if there is a way I can detect a skype call/telegram/whatsapp/fb messenger call etc in progress or incoming call etc just like the regular phone call with telephony manager/listener? I would like to have some kind of mechanism that detects an ongoing /incoming etc call from skype/telegram etc for my app. I came across this solution :Call Detection for skype in android but not sure if it'll work for all generic messenger apps. Is there a hack or any kind of listener I can implement on my side that allows me to detect these? Any ideas would be awesome.
Thanks!
You can use the AudioManager system service and check for audio mode using AudioManager#getMode(). According to the docs, AudioManager#getMode() returns the current audio mode which can be one of following:
MODE_NORMAL (0x00000000): Normal audio mode: not ringing and no call established.
MODE_RINGTONE (0x00000001): Ringing audio mode. An incoming is being signaled.
MODE_IN_CALL (0x00000002): In call audio mode. A telephony call is established.
MODE_IN_COMMUNICATION (0x00000003): In communication audio mode. An audio/video chat or VoIP call is established (added in API 11).
Using AudioManager#getMode() you can check if any other app is currently holding an audio focus of type MODE_IN_COMMUNICATION and handle your call accordingly.
AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
final int mode = am.getMode();
if(AudioManager.MODE_IN_CALL == mode){
// device is in a telephony call
} else if(AudioManager.MODE_IN_COMMUNICATION == mode){
// device is in communiation mode, i.e. in a VoIP or video call
} else if(AudioManager.MODE_RINGTONE == mode){
// device is in ringing mode, some incoming is being signalled
} else {
// device is in normal mode, no incoming and no audio being played
}
P.S. I've tested this with whatsapp messenger and it works! Cannot say the same for other messenger apps.
I am trying to identify how to route a very short audio stream (a notification) to a bluetooth headphone that is already paired with the device, while the device is ringing.
When I play any audio at any time, it is routed to the bluetooth device, no problem.
But if I try to start playing the audio when receiving an android.intent.action.PHONE_STATE, in RINGING state, the audio is not routed as expected.
I can see that the AudioManager's setBluetoothA2dpOn method has became deprecated, but I actually tried it but is seems has no effect.
I have tried the MediaRouter object, but I can see that MediaRouter.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_AUDIO) points to the RouteInfo of the Bluetooth device while the device is ringing, and the AudioManager.isBluetoothA2dpOn is true.
So, can any one tell me why the audio route is like this in the ringing moment? is there any way to force the audio to be routed to the Bluetooth device in such case?
[UPDATED]
I have tried again today and I have discovered something that may be the cause of the problem.
I have created a BroadcaseReceiver to detect the change in the android.intent.action.PHONE_STATE. if an intent is received and the state is currently ringing, check for AudioManager's mode and you will find it is MODE_NORMAL. but few seconds later the phone will start actually ringing and the mode is going to be changed into MODE_RINGTONE. trying to manually set the mode using the method setMode(AudioManager.MODE_NORMAL) is useless then, the state remains MODE_RINGTONE even after setting it to MODE_NORMAL.
Now, I think the cause of the problem is that in the MODE_RINGTONE mode, all the streams are directed to the phone speaker and here there is no way offered by the android system to change the mode.
I think the Media player realease the bluetooth connection when the phone is ringing. You can try to obtain the bluetooth audio connection and see if Media player now play through your obtained connection. You can use my class at my answer Using the Android RecognizerIntent with a bluetooth headset and see if it works. The audio in the class is Sco only.
As stated in the JavaDoc for the StartBluetoothSco method:
Note that the phone application always has the priority on the usage of the SCO connection for telephony. If this method is called while the phone is in call it will be ignored. Similarly, if a call is received or sent while an application is using the SCO connection, the connection will be lost for the application and NOT returned automatically when the call ends.`
I tried to start sco then play a music clip in normal mode, it played to the Bluetooth headset without problems, although I couldnot stop the microphone that caused the input stream plays to the headset. I then tried to call my target phone from another phone while the music is still playing, I found that the stream has got redirected automatically to the phone speaker. After the ringing mode is finished, the stream did not get redirected again to the Bluetooth headset and I think that behavior is normal according to what is stated in the JavaDoc above.
My guessing is that Android tries to protect the ringing and in-call modes as possible in order not to allow any unwanted interference from applications. In other words, when in ringing mode then no sound is going to be played to the headset until the call is accepted, and you cannot even change the AudioManager mode from ringing to another mode, your call for mode setter will be ignored.
I have tried the AudioTrack instead of MediaPlayer, but that makes no difference.
I have then tried the TextToSpeech engine like this:
in the main activity, initialize on create:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textToSpeech=new TextToSpeech(this, this);
textToSpeech.setLanguage(Locale.US);
textToSpeech.addEarcon("[wwww]", "XXXXXXXXXXXXXXXXXXXXXXX", R.raw.a);
}
in the broadcast receiver class when rining starting the Bluetooth utility class and adding the below to the onScoAudioConnected method
textToSpeech.playEarcon("[wwww]", TextToSpeech.QUEUE_FLUSH, null);
This did not work too.
I have a Samsung vibrant and I am connecting to to my car using bluetooth. In the samsung music app there is a button to route the audio to via bluetooth or via phone.
Anyone know how there were able create this functionality. I looked at the sdk and I see
ROUTE_BLUETOOTH_A2DP
This constant is deprecated. Do not
set audio routing directly, use
setSpeakerphoneOn(),
setBluetoothScoOn() methods instead.
Routing audio output to bluetooth A2DP
Constant Value: 16 (0x00000010)
but as you can see it is listed as "deprecated", i see the option for setBluetoothScoOn, but not an equivalent to for setting a2dp on.
My end goal would be to create a widget that allows me to turn on and off outing to the a2dp. So I can turn it on when I want to stream music and turn it off when I want to use navigator, but listen to music or the radio at the same time.
Here's what you are looking for: (not sure if this was available at the time of your question...)
setBluetoothA2dpOn();
But it's also deprecated.
My guess would be to use this instead:
audioManager.startBluetoothSco();
audioManager.setBluetoothScoOn(true);
And to stop routing:
audioManager.setBluetoothScoOn(false);
audioManager.stopBluetoothSco();
audioManager is a instance of the AudioManager.
Here's a reference to AudioManager: AudioManager
Hope this helps, cheers