I am developing an Android alarm clock app and I am using the STREAM_ALARM for playing the alarm audio. When I plug in headphones during the alarm playing the audio, the audio starts playing in the headphones but also continues playing in the speaker.
But I want to silence the speaker so that the user can plug in his headphones and continue listening to the audio without interrupting any people around him. This might be unusual behavior, but it's very important for this specific alarm clock app.
Maybe I could use STREAM_MUSIC, but:
The docs say that Unless your app is an alarm clock, you should play audio using the STREAM_MUSIC stream.
If the alarm starts ringing and headphones are already plugged in, I do need it to play through the speaker. STREAM_MUSIC does not do this. There might be workarounds, but I need this 100% reliable, so it'd be better to make a workaround for silencing the speaker when needed than a workaround for making it loud when needed.
I am not sure what other consequences it might have, it doesn't seem safe.
So, is there any option to force the speaker to be silent? Using some reflection maybe?
I was also considering changing the stream type on the ActionHeadsetPlug to STREAM_MUSIC, but it requires stopping the audio, recreating the MediaPlayer instance, seeking to the previous position, rebinding any events, other logic etc.. a lot of work for my use case. Silencing the speaker would definitely be better if it's possible.
Related
I know this is a very specific issue, but I'm hoping someone else has some insight.
I am using a third Party TTS (Text to Speech) and ASR (Auto Speech Recognition) library from Cerence. I've noticed on Android 12, and some Android 11 devices, when I use them together is will shut down the Audio output. I can still use the ASR for input, but no audio will be played.
I'm not seeing much in the logs for this, but when this happens, I need to disconnect the BT headset and reconnect it.
In minimal testing, Shortly after enabled Bluetooth SCO, the Audio is lost on Android 12.
AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
// Need to set mode so we continue to get the Audio in the BT headset.
am.setMode(AudioManager.MODE_IN_COMMUNICATION);
am.startBluetoothSco();
A similar thing happens on Android 11, but while I can make it fail reliably, I don't know a precise way to make it happen.
I'm wondering if anyone has any insight on how to debug audio issues. Is there certain logs I can pull or look for? Is there someway I can troubleshoot audio issues? When this happens I can't play audio in any way, as an example YouTube no longer has audio in the headset. So either the audio is being redirected somewhere else, or it has crashed.
I'm also wondering if there is another way to take control of the mic outside of Bluetooth SCO, or if there is a SCO setting I should be using that acts differently.
UPDATE:
In more testing I've realized that the AudioManager mode is being changed by something from MODE_IN_COMMUNICATION to NORMAL. I have not figures out why yet, but if I keep forcing the mode to MODE_IN_COMMUNICATION, my audio continues to be played.
I have bluetooth earbuds with great sound quality and built-in microphones. In my android bluetooth device settings, I have to switches for media profiles: 'Call audio' and 'media audio'
Behavier with both activated:
when mic not needed: high quality sound protocol (1-directional, phone to headset)
when mic needed: switches to low quality sound protocol (2-directional, headset mic also streamed to phone)
Problem: I want better audio quality during calls, because I often am on long calls (mostly on discord) and I want to listen to music in the background with great quality.
Therefore I want to use the 1-directional great protocol and the internal built-in microphone
I did some testing using the audio recorder at first:
turned off 'Call audio' switch in bluetooth settings
earbuds not recognized as possible microphone
recording startet, music on earbuds paused, internal mic was being recorded, I could listen to music in great quality (had to hit play again) on my earbuds with great quality simultaneously -> perfect
So I thought I discoverd the solution, BUT:
On Discord (or any other call app) the earbuds did not show up as a possible speaker.
When listing to music on the earbuds and then joining a call, the audio output immediatly switched to the speaker/earpiece speaker (call audio and music). Probably because the call profile was disabled.
Does anyone have a solution/workaround?
sure, wired headphones would work
Maybe there is a way to redirect my call output from discord to a media stream and then into my earbuds (Then the voice quality on discord would not improve, but I could listen to music in high quality). I found an app (BTmono) doing basically the oppsite for headsets with a call profile only: It converts your media output into a mono stream and outputs it as call audio
maybe, I can somehow mark my earbud's media profile as a call profile too
or maybe anyone got some other workaround that did not come to my mind yet.
I would really appreciate a proper solution to my problem, thanks
My question is - I need to know how many types of speaker has android phone? I mean for example regular device has one speaker and one microphone. But about speaker for example when user speak by phone hold the device near a ear, so speaker in a low volume, but also user can tap on Speaker mode and now you can hear also sound from speaker but loud. And also there one more option if user playback a music you can also hear it loud but with better quality.
Question is - is this speaker in low volume, speaker in loud volume and speaker that playback music is this one the same speaker or is it different speakers? Or maybe it is the same speaker but playback goes in different mode? Or different types?
I don't think there's a standard way to check the speaker configuration on Android. You would need to check the manufacturer specification of the handset.
The difference in quality between the voice and the music likely is due to the compression the voice undergoes in order to be transmitted in real time. The music can stream or buffer and thus can have higher fidelitiy.
It is unlikely that the difference is due specifically to the speaker configuration.
when a voice call is established, I want to play audio in an stream so that the one at the other end of the call can hear the audio, but as it is mentioned in documents it is not possible.
so I decided to play that audio through the speakers with maximum volume so that the microphone can hear it (in general this a really ugly workaround but as it is going to be done in a special situation in my app, no problem!!!).
now the problem is this that when the call is established the system reduces the volume of my audio. how to solve it ?
Which Android API can we use to set the volume level on my tablet for playing a tone when the headset is plugged in .
Currently I use the following API which does not seem to work when the headset is plugged in.
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 9, AudioManager.FLAG_SHOW_UI);
I made the following settings to route audio through the speaker when the headset is plugged in (this is the requirement of my app)
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.setSpeakerphoneOn(true);
When I play my desired tone after this setting the audio is routed through the speaker (even though headset is connected) but the volume is too high , which looks like the setStreamVolume API does not work since I have set it to only volume level 9 which is pretty low.
If I remove the headset and run my use-case then this API works fine, i.e the tone is played at a lower volume.
Is there any other API that can be used to set the volume for playing tones in Android when the headset is plugged in ?
Unless your app is a cellular call replacement, using MODE_IN_CALL actually optimizes cellular audio and starves STREAM_MUSIC on resource. If you are using STREAM_MUSIC audio with MODE_IN_CALL, depending on phone manufacturer/carrier extension of AudioPolicyManagerBase, you will see many odd behavior such as maybe the case you are seeing.
First, make sure you specify playing audio over STREAM_MUSIC. So that your volume control indeed is controlling the right stream.
Second, I would suggest use MODE_IN_COMMUNICATION instead of MODE_IN_CALL. Many manufacturer/carrier specific audio policy is specific to MODE_IN_CALL(cellular call) only.
Third, if it still happens, you should test your app on a different phone manufacturer/carrier to isolate the issue. Sometime it is a device specific flaw that you just can't fix. I have seen some cases like this myself.