2
votes

AudioManager is unreliable in onCallStateChanged. During a phone call I need it to turn on speaker phone and set the volume to max. It sometimes turns on speakerphone (usually during the second or later call) and rarely turns the volume up. My PhoneCallListener class is within my MainActivity class.

private class PhoneCallListener extends PhoneStateListener
{
    private boolean isPhoneCalling = false;

    @Override
    public void onCallStateChanged(int state, String incomingNumber)
    {
        AudioManager aM = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        aM.setMode(AudioManager.MODE_IN_CALL);
        aM.setSpeakerphoneOn(true);

        if(TelephonyManager.CALL_STATE_RINGING == state)
        {
            //phone ringing
            aM.setSpeakerphoneOn(true);
            aM.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
        }

        if(TelephonyManager.CALL_STATE_OFFHOOK == state)
        {
            //phone active
            aM.setSpeakerphoneOn(true);
            aM.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, 0);
            isPhoneCalling = true;
        }

        if(TelephonyManager.CALL_STATE_IDLE == state)
        {
            aM.setSpeakerphoneOn(false);

            if(isPhoneCalling)
            {               
                Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(i);
                isPhoneCalling = false;
            }
        }
    }
}

Within CALL_STATE_OFFHOOK I had to turn off AudioManager.FLAG_SHOW_UI because it would continually show the volume UI. Also, setting aM.setStreamVolume(AudioManager.STREAM_MUSIC, aM.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0); crashes the app for some reason.

Any suggestions on how to make AudioManager work every time so that speakerphone is on and volume is max during a phone call?


Edit: Even with setting speackphoneon to true as soon as the onCallStateChanged method is called, it still is not reliably turning the speakerphone on. The volume is also unreliable and can't seem to set it to max without it crashing.

1
Did you notice that the phone itself turns speakerphone off when receiving a call? So if you both try to set it on and off at the same time, it is no surprise it will only turn on sometimes.i Code 4 Food
This code is used when the phone places a call, not receive. When the call is made, I want speakerphone to be on.user3001127
same difference - if the phone turns it off natively, the point is that you should try waiting for 1 second before turning it on after receiving the call back, so that it doesn't get overwritten back to 'off' by the phone.i Code 4 Food

1 Answers

0
votes

Below is the code to do this. I have tested in a phone running lollipop. Write your PhoneStateListener as:

  private class myPhoneStateListener extends PhoneStateListener {
    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        super.onCallStateChanged(state, incomingNumber);

        switch (state) {

            case TelephonyManager.CALL_STATE_OFFHOOK: //Call is established
                Log.d("s@urav", "Call is Offhook now!");
                try {
                    Thread.sleep(500); //We never know when the call is actually OffHook
                } catch (InterruptedException e) {
                Log.d("s@urav","Exception is:"+e);
                }
                audioManager.setSpeakerphoneOn(true);
                break;

            case TelephonyManager.CALL_STATE_IDLE: //Call is finished
                    //Maintain a flag and do this only if speakerphone has been set on OFFHOOK
                    /*audioManager.setMode(AudioManager.MODE_NORMAL);
                    audioManager.setSpeakerphoneOn(false);*/
                break;
        }
    }
}

For raising the volume of the call you have to increase the volume of STREAM_VOICE_CALL. This code + increasing the volume of call stream will meet you requirements.