Android 音频使用问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ddxxii/article/details/79771295

一 . 关Music音频,导致System也关掉了

音频流轨道分类中
AudioManager.STREAM_MUSIC

  • system被关联了,关闭music的时候就会被关掉

二. 播放音频串音轨

  • 在呼叫过程中A(使用Call音轨),播放一段音频B(使用music音轨),正常如果不挂断,播放没问题。在播放到同时挂断就会导致B使用到A的音轨来进行播放,但播放不完全就切换回了B的音轨。

在查看代码中,发现挂断的时候,会调用

 audioManager.abandonAudioFocus(audioFocusChangeListener);

1) 查看源码:调用了service的abandonAudioFocus,移除焦点监控

 IAudioService service = getService();
        try {
            status = service.abandonAudioFocus(mAudioFocusDispatcher,
                    getIdForAudioFocusListener(l));
        } catch (RemoteException e) {
            Log.e(TAG, "Can't call abandonAudioFocus() on AudioService due to "+e);
        }

2) service的远程对应是AudioService,对应部分源码:

/** @see AudioManager#abandonAudioFocus(IAudioFocusDispatcher) */
    public int abandonAudioFocus(IAudioFocusDispatcher fl, String clientId) {
        Log.i(TAG, " AudioFocus  abandonAudioFocus() from " + clientId);
        try {
            // this will take care of notifying the new focus owner if needed
            synchronized(mAudioFocusLock) {
                removeFocusStackEntry(clientId, true);
            }
        } catch (java.util.ConcurrentModificationException cme) {
            // Catching this exception here is temporary. It is here just to prevent
            // a crash seen when the "Silent" notification is played. This is believed to be fixed
            // but this try catch block is left just to be safe.
            Log.e(TAG, "FATAL EXCEPTION AudioFocus  abandonAudioFocus() caused " + cme);
            cme.printStackTrace();
        }
        return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
    }

而removeFocusStackEntry中:
是从栈中移除,如果移除是顶部的,会让第二个重新获取焦点。

// is the current top of the focus stack abandoning focus? (because of death or request)
        if (!mFocusStack.empty() && mFocusStack.peek().mClientId.equals(clientToRemove))
        {
            //Log.i(TAG, "   removeFocusStackEntry() removing top of stack");
            mFocusStack.pop();
            if (signal) {
                // notify the new top of the stack it gained focus
                notifyTopOfAudioFocusStack();
            }
        } else {
            // focus is abandoned by a client that's not at the top of the stack,
            // no need to update focus.
            Iterator<FocusStackEntry> stackIterator = mFocusStack.iterator();
            while(stackIterator.hasNext()) {
                FocusStackEntry fse = (FocusStackEntry)stackIterator.next();
                if(fse.mClientId.equals(clientToRemove)) {
                    Log.i(TAG, " AudioFocus  abandonAudioFocus(): removing entry for "
                            + fse.mClientId);
                    mFocusStack.remove(fse);
                }
            }
        }

跟踪到这里大致知道原因了,第一个是call的音频,第二个也是call的音频,在播放B的时候,没有挂断这边快,所以并没有加入到顶部焦点。就导致移除后让第二个call获取到焦点,使用到它播放了。

  • 解决办法
    在挂断的时候,延迟2秒,让B加载完成到焦点顶部,这样移除的时候就只会移除call,不会再notify了。

猜你喜欢

转载自blog.csdn.net/ddxxii/article/details/79771295