当在相同添加的通话中,Android 9和10上使用OpenTok(Tokbox)时,会出现音频焦点请求被拒绝的情况。

8

Android 电信管理器:新增VOIP通话没有声音

我正在尝试在我的应用中添加VOIP视频通话。我已经注册了电话账户并将通话添加到TelecomManager。通话已成功接受。我已经实现了Connection和ConnectionService。

我正在使用以下代码添加通话:

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);

我正在使用以下代码来接听响铃电话。

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);
}

我已尝试请求音频焦点,但当我在电信管理器中添加呼叫时,我的应用程序会失去焦点,因为手机开始响铃。在接听电话后,应用程序无法重新获得焦点,我相信电信/通话具有焦点,但我什么都听不见。通话中的另一个人可以毫无问题地听到我。当我结束通话后,应用程序会重新获得焦点。
我在日志中可以看到以下内容。
    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 !

以下是我用于请求音频的代码。

 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;
    }

如果我不使用TelecomManager建立VOIP连接,一切都正常。所以我相信当我添加和接受电话时出了问题。

感谢任何想法或修复。


1
嘿,马利克,我没有看到你实际请求音频焦点的代码。通常,您会创建一个AudioFocusRequest,在您的情况下,使用语音通信AudioAttribute与请求是合适的。我浏览了一下opentok代码,没有看到他们在任何地方为您请求音频焦点。因此,在添加呼叫之前,您可能需要自己请求它。您还可以使用此功能通过监听器中的音频焦点更改来检测您的应用程序是否真正失去了音频焦点。 - Cheesebaron
嘿@Cheesebaron,感谢您的关注。我已经添加了请求音频焦点的代码。当我在telecomManager中添加调用时,应用程序会失去焦点,一旦我结束通话,应用程序就会再次获得焦点。 - Basit ZIa
@BasitZIa,可以告诉我你的安卓版本吗? - Kiran Maniya
3个回答

1
你无法听到声音的原因是OpenTok遵循RequestAudioFocus的结果。由于音频焦点请求失败,OpenTok将不会播放音频。你可以找出RequestAudioFocus失败的原因,或者下载Xamarin.OpenTok.Android 2.14.2以便即使RequestAudioFocus失败也能播放音频。

我想知道为什么是2.14.2?如果有任何细节,我将不胜感激。 - Alex Sorokoletov
@AlexSorokoletov 可能是因为他们以不同的方式请求音频焦点。或者即使 AudioFocusRequest 被拒绝,他们仍然继续播放音频。在后来的版本中,我认为他们会暂停/停止音频。在 OpenTok 的人回复之前,我只能猜测。一旦发布完成,我将花些时间找到具体/确切的原因。 - Basit ZIa
谢谢@BasitZIa。2.14.2是一个相当旧的版本,所以我对这个建议感到惊讶(不仅是回滚到以前的版本,而是回滚到那个特定的版本)。 - Alex Sorokoletov

0

你应该使用 AudioManager.AUDIOFOCUS_GAIN 或者 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT 来请求音频焦点。在这里,当接收到电话时,你将会请求一个未定义的时间,因此强烈建议使用 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT 来请求音频焦点。以下是代码片段。

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
}

通过在setOnAudioFocusChangeListener中设置监听器回调函数,您可以监听音频焦点的变化。
在Android N及更早版本中,您可以声明此意图而不使用AudioFocusRequest对象,如下面的代码片段所示。 您仍然必须实现AudioManager.OnAudioFocusChangeListener以响应状态更改。 这是与上面片段等效的代码。
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
}

作为最后一句话,当您的应用程序完成播放音频时,应通过调用AudioManager.abandonAudioFocus(…)来放弃音频焦点。
对于您提供的代码,如果OpenTok不处理音频焦点,则必须在调用AcceptRingingCall()方法之前请求音频焦点。您可以参考官方Android 文档

1
我认为他们试图处理音频焦点,如果音频焦点请求被拒绝,他们就不会播放音频。暂时降级到2.14.2可以解决问题。 - Basit ZIa
这就是我所说的,看第一个片段:switch (focusRequest) { case AudioManager.AUDIOFOCUS_REQUEST_FAILED: // 不要开始播放 case AudioManager.AUDIOFOCUS_REQUEST_GRANTED: // 实际上开始播放 } - Kiran Maniya

0

我有同样的问题。这里有一个解决方法,可能不是“正确”的方法,但对我有效。在我的VOIP呼叫活动中,一旦建立了VOIP连接,我使用以下代码来关闭我的Connection对象:

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

而且OpenTok重新获得了音频焦点。传入的音频正常工作。我还不知道提前终止Connection对象的潜在后果(无法执行其他呼叫功能,如保持通话、与其他传入呼叫进行交互等)。但在找到Connection放弃音频焦点的另一种方法之前,我只能这样做。


是的,这些都是后果。另外一个后果就是拨打紧急号码。我不知道如果用户开始拨打紧急号码系统会如何反应。对我们来说,这些情况非常重要,所以我们仍在使用旧版本的SDK。我尝试升级到新版本,但我们开始遇到更多问题。 - Basit ZIa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接