Android 8.0后音频焦点处理小结

Android  2020年10月14日 pm10:12发布4年前 (2020)更新 91es.com站长
81 0 0

前提

两个或两个以上的 Android 应用可同时向同一输出流播放音频,系统会将所有音频流混合在一起。为了避免所有音乐应用同时播放,Android 引入了“音频焦点”的概念。

一次只能有一个应用获得音频焦点。

音频焦点采用合作模式

对,合作模式,你可以准守也可以不准守。

Android建议应用遵守音频焦点准则,但系统不会强制执行这些准则。如果应用想要在失去音频焦点后继续大声播放,系统无法阻止它。

下面我们只关心Android 8.0 以后版本的焦点申请。

requestAudioFocus()的使用

// 初始化AudioManager

AudioManager mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);

// mAudioAttributes 配置(多媒体场景,申请的是音乐流)
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) //设置是否允许延迟获取焦点
.setWillPauseWhenDucked(true) //设置AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK会暂停,系统不会压低声音
.setOnAudioFocusChangeListener(mFocusChangeListener) //设置焦点监听回调
.build();

// requestAudioFocusshe申请焦点
int audioStatus = mAudioManager.requestAudioFocus(mAudioFocusRequest);

申请的焦点类型

申请的焦点类型有如下几种

  1. AudioManager.AUDIOFOCUS_GAIN

永久获取焦点

其他应用监听OnAudioFocusChangeListener 收到的焦点状态变化是AudioManager.AUDIOFOCUS_LOSS。

  1. AudioManager.AUDIOFOCUS_GAIN_TRANSIENT

临时获取焦点

其他应用监听OnAudioFocusChangeListener 收到的焦点状态变化是AudioManager.AUDIOFOCUS_LOSS_TRANSIENT。

  1. AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK

临时获取焦点且可以被压低声音播放

其他应用监听OnAudioFocusChangeListener 收到的焦点状态变化是AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK。

  1. AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE

用于指示音频焦点的临时请求,预计将持续很短的时间,在此期间,其他任何应用程序或系统组件均不应播放任何内容。 专用音频音频请求和瞬时音频焦点请求的示例包括语音备忘录记录和语音识别,在此期间,系统不应播放任何通知,并且媒体播放应已暂停。(此部分来自于谷歌翻译Android文档)

申请焦点回调的状态值

audioStatus 为焦点状态,有三种情况

  1. AUDIOFOCUS_REQUEST_FAILED = 0

焦点申请失败,不能播放

  1. AUDIOFOCUS_REQUEST_GRANTED = 1

焦点申请成功,可以播放

  1. AUDIOFOCUS_REQUEST_DELAYED = 2

焦点延迟获取,不可以播放。

如果有重新获取焦点,会通过onAudioFocusChange()进行回调才可以播放。

这个需要在AudioFocusRequest.Builder通过setAcceptsDelayedFocusGain(boolean)允许延迟获取焦点。

private OnAudioFocusChangeListener mFocusChangeListener = new OnAudioFocusChangeListener() {
        @Override
        public void onAudioFocusChange(int focusChange) {
            Log.i(TAG, "mdeia_onAudioFocusChange:" + focusChange);
            try {
                switch (focusChange) {
                    case AudioManager.AUDIOFOCUS_LOSS:
                        break;
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                        break;
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                        break;
                    case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
                        break;
                    case AudioManager.AUDIOFOCUS_GAIN:
                        break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

通过onAudioFocusChange()的回调是表示重新获取或丢失焦点。

  1. AUDIOFOCUS_LOSS 永久丢失焦点

其他应用申请的是永久焦点,我们应用就会永久丢失焦点,然后不能发声,且需要释放资源。

如果要发声需要重新走申请流程。

  1. AUDIOFOCUS_LOSS_TRANSIENT

临时丢失焦点

  1. AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK

临时丢失焦,但可以播放,且声音被压低的

  1. AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE

临时丢失,不可以播放(具体看上面解)

  1. AUDIOFOCUS_GAIN

重新获取焦点或者是延迟获取焦点时的回调,可以播放

参考文章

  1. Android音频焦点处理
  2. Android官方文档-管理音频焦点
  3. Android音频焦点处理

 历史上的今天

  1. 2024: Android ContentProvider使用记录(0条评论)
  2. 2021: 冰心:我们把春天吵醒了(0条评论)
  3. 2019: 张晓风:经济学的旁听生(0条评论)
版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站内容: 部分来源于网络,仅供学习和参考,若侵权请留言
3、 本站申明: 个人流水账日记,内容并不保证有效

暂无评论

暂无评论...

随机推荐

季羡林:漫谈人生的意义和价值

当我还是一个青年大学生的时候,报纸杂志上曾刮起一阵讨论人生的意义与价值的微风,文章写了一些,议论也发表了一通。我看过一些文章,但自己并没有参加进去。原因是,有的文章不知所云,我看不懂。更重要的是,我认为这种讨论本身就无意义,无价值,不如实实在在地干几件事好。时光流逝,一转眼,自己已经到了望九之年,...

一招永久去除WPS推送广告

前言WPS是国内优秀的办公软件,非常好用和优秀,但广告太多太烦人了。是不是弹出一个,让人有点[恶心]。本文参考其网有文章,摘抄于此。PS: 仅仅在Window系统上验证过。正文打开WPS的配置工具(一般是菜单-》WPS Office-》WPS Office 工具-》配置工具)打开后选择...

Android View Binding的使用简介

前言简单记录一下,方便自己查阅。好记性不如烂笔头正文PS: 本文内容大都摘抄,感谢什么是View BindingView Binding是Android Studio 3.6推出的新特性,目的是为了替代findViewById(内部实现还是使用findViewById)。在启动视图绑...

龙应台:我为什么要求你读书

那天我问你,“你将来想做什么”,我注意到,你很不屑于回答我这个问题,所以跟我胡诌一通。是因为你们这个时代的人,对未来太自信,所以不屑与像我这一代人年轻时一样,讲究勤勤恳恳、如履薄冰,还是其实你们对于未来太没信心,所以假装出一种嘲讽和狂妄的姿态,来闪避我的追问?我几乎要相信,你是在假装潇洒了。今天的...

RecyclerView的简单实用

RecyclerVier简介RecyclerView是Android一个更强大的控件,其不仅可以实现和ListView同样的效果,还有优化了ListView中的各种不足。其可以实现数据纵向滚动,也可以实现横向滚动(ListView做不到横向滚动)。添加RecyclerView 依赖库 ...

ListView和GridView替换滑动条图片

前言记录一下AbsListView(ListView和GridView等)替换快速滑动条的几种方式。这里设计使用Java代码和xml配置方式。记录于此,方便自己查阅。正文主要涉及AbsListView的之类的修改。一般是换肤插件需要。隐藏内容!付费阅读后才能查看!¥2 ¥3多个隐藏块...