androidandroid-audiomanagerspeakerphone

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.


Solution

  • 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.