@@ -373,10 +373,19 @@ public void setAudioMode() {
373373 AudioManager audioManager = (AudioManager )
374374 context .getSystemService (Context .AUDIO_SERVICE );
375375
376- int mode = AudioManager .MODE_NORMAL ;
376+ // change the audio mode and request/abandon audio focus according to phone state,
377+ // but only on audio mode transitions
377378 switch (getState ()) {
378379 case RINGING :
379- mode = AudioManager .MODE_RINGTONE ;
380+ if (audioManager .getMode () != AudioManager .MODE_RINGTONE ) {
381+ // only request audio focus if the ringtone is going to be heard
382+ if (audioManager .getStreamVolume (AudioManager .STREAM_RING ) > 0 ) {
383+ if (VDBG ) Log .d (LOG_TAG , "requestAudioFocus on STREAM_RING" );
384+ audioManager .requestAudioFocusForCall (AudioManager .STREAM_RING ,
385+ AudioManager .AUDIOFOCUS_GAIN_TRANSIENT );
386+ }
387+ audioManager .setMode (AudioManager .MODE_RINGTONE );
388+ }
380389 break ;
381390 case OFFHOOK :
382391 Phone offhookPhone = getFgPhone ();
@@ -386,18 +395,28 @@ public void setAudioMode() {
386395 offhookPhone = getBgPhone ();
387396 }
388397
398+ int newAudioMode = AudioManager .MODE_IN_CALL ;
389399 if (offhookPhone instanceof SipPhone ) {
390- // enable IN_COMMUNICATION audio mode for sipPhone
391- mode = AudioManager .MODE_IN_COMMUNICATION ;
392- } else {
393- // enable IN_CALL audio mode for telephony
394- mode = AudioManager .MODE_IN_CALL ;
400+ // enable IN_COMMUNICATION audio mode instead for sipPhone
401+ newAudioMode = AudioManager .MODE_IN_COMMUNICATION ;
402+ }
403+ if (audioManager .getMode () != newAudioMode ) {
404+ // request audio focus before setting the new mode
405+ if (VDBG ) Log .d (LOG_TAG , "requestAudioFocus on STREAM_VOICE_CALL" );
406+ audioManager .requestAudioFocusForCall (AudioManager .STREAM_VOICE_CALL ,
407+ AudioManager .AUDIOFOCUS_GAIN_TRANSIENT );
408+ audioManager .setMode (newAudioMode );
409+ }
410+ break ;
411+ case IDLE :
412+ if (audioManager .getMode () != AudioManager .MODE_NORMAL ) {
413+ audioManager .setMode (AudioManager .MODE_NORMAL );
414+ if (VDBG ) Log .d (LOG_TAG , "abandonAudioFocus" );
415+ // abandon audio focus after the mode has been set back to normal
416+ audioManager .abandonAudioFocusForCall ();
395417 }
396418 break ;
397419 }
398- // calling audioManager.setMode() multiple times in a short period of
399- // time seems to break the audio recorder in in-call mode
400- if (audioManager .getMode () != mode ) audioManager .setMode (mode );
401420 }
402421
403422 private Context getContext () {
0 commit comments