Audio in Video Call(Android_M)

相关:

  • InCallScreen中CallButton界面更新介绍(audioButton等)
  • Audio in Video Call(Android_L)
  • Audio in Video Call(Android_M)
  • CallAudioManager initiate and work

在前一篇中我简单介绍了在Android L 版本中Video Call中audio切换的一些信息,本篇以QCOM Release的Android M版本为基础看一下6.0上的Video Call中的audio相关变化。

文件变化

比较明显的变化是 M上InCallUI中新增了一个类InCallAudioManager.java,见名知意,这是一个专门管理通话中Audio状态的类。
先看一下这个类里有那些方法:


图1: 文件结构
从方法名上可以大致看出这是一个管理call在 upgrade、modify和merge时候去开启扬声器或听筒的类。
先声明一点,enableSpeaekr()和enableEarpiece()两个方法不是被调用了就一定会产生AudioMode的变化,具体的判断条件我们放到最后再讲。

我们先看一下两个方法的调用层级:

enableSpeaker() 的调用层级

Audio in Video Call(Android_M)_第1张图片
图2: enableSpeaker()方法调用层级
上面这张图可解释为3个打开Speaker的场景:
1. 当点击合并通话时;
2. 当接受升级为视频电话是;
3. 当更改通话类型时。

其中第1种:当合并的两路通话中有一路是视频电话时打开Speaker:

    /** * Called when user clicks on merge calls from the UI. Route audio to speaker if one of the * calls being merged is a video call. */
    public void onMergeClicked() {
        Log.v(this, "onMergeClicked");

        if (CallUtils.isVideoCall(CallList.getInstance().getBackgroundCall()) ||
                CallUtils.isVideoCall(CallList.getInstance().getActiveCall())) {
            enableSpeaker();
        }
    }

ModifyCall有两种情况,我们放到下面跟enableEarpiece一起说。

enableEarpiece()的调用层级

Audio in Video Call(Android_M)_第2张图片
图3: enableEarpiece()方法调用层级
可以看到打开听筒的唯一调用地方是ModifyCall,ModifyCallClicked()方法代码如下:

    /** * Called when user sends an upgrade/downgrade request. Route audio to speaker if the user * sends an upgrade request to Video (bidirectional, transmit or receive) otherwise route * audio to earpiece if it's a downgrade request. */
    public void onModifyCallClicked(final Call call,final int newVideoState) {
        Log.v(this, "onModifyCallClicked: Call = " + call + "new video state = " +
                newVideoState);

        if (!VideoProfile.isVideo(newVideoState)) {
            enableEarpiece();
        } else if (canEnableSpeaker(call.getVideoState(),newVideoState)) {
            enableSpeaker();
        }
    }

可解释为:升级为视频电话时打开Speaker,降级时打开Earpiece。

实际AudioMode是否变换?

前面我们说过及时调用了这两个方法也不会一定产生AudioMode的变化,enableSpeaker()方法前的注释里已经写得很清楚了。
当现在蓝牙和有线耳机没有连接,且当前audio不是通过Speaker传送的话,打开Speaker。听筒同理。
(我觉得QtiCallUtils.isEnabled()方法有点意思,可以打开看看)

    /** * Routes the call to the speaker if audio is not being already routed to Speaker and if * bluetooth or wired headset is not connected. */
    private static void enableSpeaker() {
        final TelecomAdapter telecomAdapter = TelecomAdapter.getInstance();
        if (telecomAdapter == null) {
            Log.e(LOG_TAG, "enableSpeaker: TelecomAdapter is null");
            return;
        }

        final int currentAudioMode = AudioModeProvider.getInstance().getAudioMode();
        Log.v(LOG_TAG, "enableSpeaker: Current audio mode is - " + currentAudioMode);

        if(!QtiCallUtils.isEnabled(CallAudioState.ROUTE_SPEAKER |
                CallAudioState.ROUTE_BLUETOOTH | CallAudioState.ROUTE_WIRED_HEADSET,
                currentAudioMode)) {
            Log.v(LOG_TAG, "enableSpeaker: Set audio route to speaker");
            telecomAdapter.setAudioRoute(CallAudioState.ROUTE_SPEAKER);
        }
    }

补充

到这就完了么?上面我们从代码中推出了一些场景以及实现,那么在实际使用中以现有的代码能满足用户需要么?
这个问题先留在这,等后面如果项目上有报相关的bug的时候我再来更新。
1. 视频电话降级为语音电话关闭Speaker

这个我在前一篇博客中写到过,不过依现在M上的代码来看,只有发起降级的一端会关闭Speaker,接收端的AudioMode貌似不会更改。不过这种现象也可以理解,对方没有准备的情况下,扬声器突然关掉了的话,而假如用户又没有意识到的话,会听不到通话另一方的声音的。

你可能感兴趣的:(android,video,audio)