一 AOSP AudioMnager.java 中对外暴露的API
1 申请音频焦点
public int requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint)
示例:
mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
public int requestAudioFocus(@NonNull AudioFocusRequest focusRequest)
示例:
mFocusRequest = new AudioFocusRequest
.Builder(focusRequest)
.setAudioAttributes(mAttrib)
.setOnAudioFocusChangeListener(mFocusListener)
.setForceDucking(false)
.setWillPauseWhenDucked(false)
.setAcceptsDelayedFocusGain(false)
.build();
ret = mAudioManager.requestAudioFocus(mFocusRequest);
其余这种都是隐藏的只能系统应用调用的API
2 释放音频焦点
public int abandonAudioFocusRequest(@NonNull AudioFocusRequest focusRequest)
示例:mAudioManager.abandonAudioFocusRequest(mFocusRequest)
public int abandonAudioFocus(OnAudioFocusChangeListener l)
示例:mAudioManager.abandonAudioFocus(mAudioFocusListener)
二 AOSP AudioManager requestAudioFocus /abandonAudioFocus 的时序图
接口一 :
public int requestAudioFocus(@NonNull AudioFocusRequest focusRequest)
public int requestAudioFocus(@NonNull AudioFocusRequest afr, @Nullable AudioPolicy ap)
public void registerAudioFocusRequest(@NonNull AudioFocusRequest afr)
mAudioFocusIdListenerMap.put(key, fri); 将afr的listener加入map
status = service.requestAudioFocus(afr.getAudioAttributes(),//调用的音频attribute场景
afr.getFocusGain(),//申请的焦点类型
mICallBack,//应用侧的binder线层
mAudioFocusDispatcher,//这个用来指示dispatchAudioFocusChange焦点变化的回调
clientId,//一般是应用的标识android.media.AudioManager@9d3bd79com.ximalaya.ting.android.opensdk.player.service.ad$3@778babe
getContext().getOpPackageName() /* package name */, //应用包名
afr.getFlags(),//指示是否延迟获取焦点的标记
ap != null ? ap.cb() : null,//是否有额外的policy
sdk);//sdk版本标记
说明:AOSP的应用requestAudioFocus,流程中会遍历已有的mFocusStack栈中的clinetid,找到相同的clientId先remove,然后在回调listenner轮询通知之前的client,焦点状态的变化,最终将这个clientid 放入栈顶。abandonAudioFocus 与之相反。
ps:上图是使用drawio 画的,导出为图片,然后附上去的,因为比较大,所以模糊,需要仔细看的,可以另存为,然后电脑上打开,放大看,应该可以看到细节