Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using AudioManager interferes with call audio

I'm using the following code in a BroadcastReceiver (phone state listener) to enable speakerphone:

final Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
    @Override
    public void run() {
        AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
        audioManager.setMode(AudioManager.MODE_IN_CALL);
        audioManager.setSpeakerphoneOn(true);
    }
}, 500);

This happens when a new outgoing call is initiated via my app. When the call is disconnected, I turn speakerphone off:

AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager.setSpeakerphoneOn(false);

This all seems to work well...the first time. Afterward, my phone's audio streams seem to be tangled up into a mess. Subsequent calls are strangely silent, even calls made from outside my app's code (where the settings above are not triggered). I can get call audio back seemingly at random, but I'm not sure what causes it to return.

Any ideas on what I could be doing wrong? Is there an Android bug I'm not aware of? How can I avoid silencing my audio for subsequent calls?

EDIT: I'm testing on a Galaxy S4.

like image 406
JstnPwll Avatar asked Oct 16 '14 14:10

JstnPwll


People also ask

What is audio focus in android?

Audio focus is managed by the system. The system forces audio playback from an app to fade out when another app requests audio focus. In addition, the system also mutes audio playback when an incoming call is received. Android 8.0 (API level 26) through Android 11 (API level 30)

What is an audio manager?

Audio Manager in android is a class that provides access to the volume and modes of the device. Android audio manager helps us adjust the volume and ringing modes of devices based on our requirements. The modes that are well known to us, that are Ringing, Vibration, Loud, Silent, etc.

How do I use Audio Manager?

You can easily control your ringer volume and ringer profile i-e:(silent,vibrate,loud e.t.c) in android. Android provides AudioManager class that provides access to these controls. In order to use AndroidManager class, you have to first create an object of AudioManager class by calling the getSystemService() method.


2 Answers

I have solved this issue. It seems the code that was screwing up my audio was this line:

audioManager.setMode(AudioManager.MODE_IN_CALL);

I had used this method because I couldn't get the speakerphone setting to engage successfully without it (I found a suggestion to set the mode in another Stack Overflow answer...it worked, but had problematic consequences).

All I really had to do was remove this line and increase the handler delay from 500 to 2000.

I've also maintained a static reference to the AudioManager as suggested in this answer. It doesn't seem to be necessary in this particular case, but better safe than sorry.

like image 64
JstnPwll Avatar answered Nov 08 '22 23:11

JstnPwll


First of, I will copy this text from the documentation of setMode, just to be sure you are having it into account:

The audio mode encompasses audio routing AND the behavior of the telephony layer.
Therefore this method should only be used by applications that replace the platform-wide 
management of audio settings or the main telephony application

In other words, only une application on the system should be toying with this kind of methods. If done otherwise, consistency is not assured.

Then I would check your different audio streams in case you have some of them too low ( STREAM_VOICE_CALL, STREAM_SYSTEM, STREAM_RING, STREAM_MUSIC or STREAM_ALARM). And maybe try to use setStreamMute instead of setSpeakerphoneOn.

It would be helpful to know if your application is in fact replacing the platform-wide management of audio settings or the main telephony application

like image 21
Logain Avatar answered Nov 08 '22 21:11

Logain