7

Android Telecom Manager no incoming audio/sound on an Added VOIP call

I am trying to add a VOIP video calls in my app. I have registered the phone account and added the call to TelecomManager. Call is accepted successfully. I have already implemented Connection and ConnectionService.

I am using the below code to add a call.

var uri = Android.Net.Uri.FromParts(PhoneAccount.SchemeSip, voipCallInfo.Payload?.CallerName, null);
extras.PutParcelable(TelecomManager.ExtraIncomingCallAddress, uri);
extras.PutParcelable(TelecomManager.ExtraPhoneAccountHandle, phoneAccountHandle);
telecomManager.AddNewIncomingCall(phoneAccountHandle, extras);

and I am using the below code to accept the ringing call.

var telecomManager = GetTelecomManager();
if (telecomManager == null)
{
     logger.Error("Telecom Manager is null, May be permissions not granted");
     return;
}
try
{
     .
     .
     .
     telecomManager.AcceptRingingCall();
     .
     .
}
catch (Exception ex)
{
     logger.Error("RequestSystemToAnswerCall Exception : " + ex.Message);
}

I have tried to request the audio focus, but when I add a call in the telecom manager my app loses the focus because the phone starts ringing. After I accept the call app doesn't get the focus back I believe Telecom/Call has the focus but I can't hear anything. Another person on the call can hear me without a problem. When I end the call apps get the focus back.

I can see below in the logs.

    2020-06-22,14:09:34.831 WebRTCManager Trace IsAudioSubscriptionEnabled True 
[AudioManager] Use of stream types is deprecated for operations other than volume control
[AudioManager] See the documentation of requestAudioFocus() for what to use instead with android.media.AudioAttributes to qualify your playback use case
[AUDIO_FOCUS] Audio Focus request DENIED !

Below is the code I am using for requesting Audio.

 public bool RequestAudioFocus()
    {
        var amanager = (AudioManager)GetSystemService(AudioService);
        AudioFocusRequest audioFocusRequest;
        if (Build.VERSION.SdkInt > BuildVersionCodes.O)
        {
            audioFocusRequest = amanager.RequestAudioFocus(new AudioFocusRequestClass.Builder(AudioFocus.Gain)
                                       .SetAudioAttributes(new AudioAttributes.Builder().SetLegacyStreamType(Stream.VoiceCall).Build())
                                       .SetOnAudioFocusChangeListener(this)
                                       .Build());
        }
        else
        {
            audioFocusRequest = amanager.RequestAudioFocus(this, Stream.VoiceCall, AudioFocus.Gain);
        }

        Debug.WriteLine("MainActivity RequestAudioFocus audioFocusRequest : " + audioFocusRequest);

        if (audioFocusRequest == AudioFocusRequest.Granted)
        {

            return true;
        }
        return false;
    }

When I establish a VOIP connection without using TelecomManager. Everythings work fine. So I believe something goes wrong when I add and accept the call.

Thanks for any idea or fix.

Basit ZIa
  • 846
  • 1
  • 8
  • 24
  • 1
    Hey Malik, I don't see the code where you actually request audio focus. Usually you would create a `AudioFocusRequest` and in your case it would be appropriate to Voice Communication `AudioAttribute` with the request. I've browsed a bit around the opentok code and don't see anywhere they request the Audio Focus for you. So you probably have to request it yourself prior to adding the call. You could also use this to detect if your App really loses the Audio Focus though the audio focus change in the listener. – Cheesebaron Jun 25 '20 at 19:15
  • Hey @Cheesebaron Thanks for looking into it. I have added the code I use for requesting audio focus. App losses the focus when I add the call in telecomManager as soon as I end the call app gains the focus again. – Basit ZIa Jun 25 '20 at 22:26
  • @BasitZIa may i know android version, please? – Kiran Maniya Jun 25 '20 at 23:00

3 Answers3

1

The reason why you can't hear anything is because OpenTok obeys the result of the RequestAudioFocus. Since the audio focus request fails OpenTok will not play audio. You can either find out why RequestAudioFocus fails or download to Xamarin.OpenTok.Android 2.14.2 in order to play audio even if RequestAudioFocus fails.

thorsen
  • 126
  • 1
  • I was wondering why exactly 2.14.2? I would appreciate any details on that. – Alex Sorokoletov Jun 30 '20 at 20:07
  • @AlexSorokoletov Probably because they are requesting audio focus differently. OR they continue playing the audio even if AudioFocusRequest is denied. In later version, I think they are pausing/stopping the audio. I can only guess until we hear from OpenTok guys. I will spend some time on finding the specific/exact reason once I am done with the release. – Basit ZIa Jul 02 '20 at 12:33
  • Thank you @BasitZIa. 2.14.2 is rather an old version, so I was surprised by that advise (not just rollback to previous version but to that specific). – Alex Sorokoletov Jul 03 '20 at 05:48
0

You should use AudioManager.AUDIOFOCUS_GAIN or AudioManager.AUDIOFOCUS_GAIN_TRANSIENT to request the audio focus. Here you are going to request for an undefined amount of time when call is received, so using the AudioManager.AUDIOFOCUS_GAIN_TRANSIENT is highly recommended for audio focus request. Here is the code snippet.

AudioManager mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
AudioAttributes mAudioAttributes =
       new AudioAttributes.Builder()
               .setUsage(AudioAttributes.USAGE_MEDIA)
               .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
               .build();
AudioFocusRequest mAudioFocusRequest =
       new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
               .setAudioAttributes(mAudioAttributes)
               .setAcceptsDelayedFocusGain(true)
               .setOnAudioFocusChangeListener(...) // Need to implement listener
               .build();
int focusRequest = mAudioManager.requestAudioFocus(mAudioFocusRequest);
switch (focusRequest) {
   case AudioManager.AUDIOFOCUS_REQUEST_FAILED:
       // don’t start playback
   case AudioManager.AUDIOFOCUS_REQUEST_GRANTED:
       // actually start playback
}

By setting the listener callback function in setOnAudioFocusChangeListener you can listen to the audio focus change.

On Android N and earlier you can declare this intention without using the AudioFocusRequest object as shown below snippet. You still have to implement AudioManager.OnAudioFocusChangeListener to react to the status change. Here’s the equivalent code to the snippet above.

AudioManager mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
int focusRequest = mAudioManager.requestAudioFocus(
..., // Need to implement listener
       AudioManager.STREAM_MUSIC,
       AudioManager.AUDIOFOCUS_GAIN);
switch (focusRequest) {
   case AudioManager.AUDIOFOCUS_REQUEST_FAILED:
       // don't start
   case AudioManager.AUDIOFOCUS_REQUEST_GRANTED:
       // start
}

As a final word, When your app has completed playing it’s audio, then it should abandon audio focus by calling AudioManager.abandonAudioFocus(…).

For your given code, if the OpenTok doesn't handle audio focus, You have to request the audio focus before AcceptRingingCall() method call. You can follow the official android docs.

Kiran Maniya
  • 5,637
  • 4
  • 34
  • 53
  • 1
    I think they try to handle the audio focus and if the audio focus request is denied they don't play the audio. Downgrading to 2.14.2 works for now. – Basit ZIa Jun 26 '20 at 09:28
  • That's what i said see first snippet switch (focusRequest) { case AudioManager.AUDIOFOCUS_REQUEST_FAILED: // don’t start playback case AudioManager.AUDIOFOCUS_REQUEST_GRANTED: // actually start playback } – Kiran Maniya Jun 26 '20 at 09:32
0

I have the same problem. Here's a fix that probably isn't the 'right' way to do it, but works for me. In my VOIP call activity, once VOIP connection established, I kill my Connection object with:

mCallConnection.onDisconnect();
mCallConnection.destroy();

And OpenTok gains the audio focus back. Incoming audio works. I don't yet know the potential consequences of killing the Connection object early (can't perform other call functions like hold, interact with other incoming calls, etc.). But until I find another way for Connection to abandon its audio focus, I'll have to do this.

  • Yes those are the consequences. One more is calling an emergency number. I don't how the system will behave in case the user starts calling an emergency number. For us, these situations were important so we are still using the old version of the SDK. I tried updating to a newer version but we started facing more issues. – Basit ZIa Sep 17 '20 at 07:08