Android API to set volume level - android

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.

Related

Losing Audio while connect to Bluetooth SCO

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.

Android audio with STREAM_ALARM - how to silence speaker when headphones plugged

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.

How to set type to my audio so it will be treated like a call?

I'm making VoIP app on Android, playing PCM audio like in Play PCM stream in Android
On my phone (LG V20, Android8) it works, but when I'm using volume buttons, it doesn't show Call volume and volume control doesn't work for my audio at all.
How to make my audio "Call audio" and be controlled by standard volume controls?
You have to take AudioFocus by calling "requestAudioFocus()": https://developer.android.com/reference/android/media/AudioManager#requestAudioFocus(android.media.AudioFocusRequest) and set VOICECALL Stream in the Constructor of the Request.
In the end, I was missing:
Permission - MODIFY_AUDIO_SETTINGS
Setting AudioManager mode to MODE_IN_COMMUNICATION
I'm surprised it wasn't in tutorials, maybe it was changed in later SDK.

Low call volume using dedicated phone number with Twilio Programmable Voice Android

Tried experimenting with different audio focuses: AUDIOFOCUS_GAIN_TRANSIENT, AUDIOFOCUS_GAIN
Tried multiple Audio manager modes: MODE_IN_COMMUNICATION, MODE_IN_CALL
Call volume is noticeably quieter than a normal phone call.
All volume levels are set to max.

How to route audio to non default sound card on Android for specific usecase?

I'm working on custom board running Android 4.2.1. I have almost all things working except of proper audio routing.
I have an audio codec there (WM8960 connected in I2S bus) and it works well servicing speakers, built-in microphone, headphones and headphones-mic. The HAL is implemented through tinyAlsa in audio_hw.c like usual and works perfectly in whole system.
There is also second audio device (actually a USB sound card) with GSM modem audio connected. It is detected by ALSA without problems and I can use it on kernel level using aplay/arecord.
Now I need to set proper routing when an audio call is established -- that means that I have to play the sound from microphone to second audio device and vice versa. Can please someone give me an advice or example how to handle this using tinyAlsa API?
regards
Jan
I think you can solve this problem in Audio HAL.
Assuming second audio device you meant is second audio card
When a call usecase is detected, change the playback sound card to the second audio card.
i.e if
Card0 - WM8960;
Card1 - USB sound card
change card number in pcm_open API
pcm_open(0, ..) change to
pcm_open(1, ..)
you might also need to set corresponding mixer commands before invoking pcm_open.

Categories

Resources