首页 > 其他分享 >Android中的Audio播放:竞争Audio…

Android中的Audio播放:竞争Audio…

时间:2023-07-28 18:31:51浏览次数:40  
标签:AUDIOFOCUS 播放 程序 Focus AudioFocus Android Audio


Android是多任务系统,Audio系统是竞争资源。Android2.2之前,没有内建的机制来解决多个程序竞争Audio的问题,2.2引入了称作AudioFocus的机制来管理对Audio资源的竞争的管理与协调。本文主要讲解AudioFocus的使用。

按照AudioFocus的机制,在使用AudioStream之前,需要申请AudioFocus,在获得AudioFocus之后才可以使用相应的AudioStream;如果有别的程序竞争你正在使用的AudioStream,你的程序需要在收到通知之后做停止播放或者降低声音的处理。值得指出的是,这种机制是需要合作完成的,需要所有使用Audio资源的程序都按照这种机制来做,而如果有程序在它失去AudioFocus的时候仍然在使用Audio,AudioFocus拿它也没办法。而这一点对于开放系统的Android来说很致命的:用户可能安装没遵守这种机制的程序,或者版本太老还没引入这种机制的程序,这最终会导致很差的用户体验。

对于手机方案公司来说,要做的能做的事情就是教育和培训团队成员以保证自己内建的程序遵守机制没问题,这包括了Android原生的程序、自己开发的程序,以及适配第三方的程序。


一、AudioFocus的申请与释放

下面看与AudioFocus的相关的类:


Android中的Audio播放:竞争Audio…_App


获取/放弃AudioFocus的方法都在android.media.AudioManager中,获取AudioFocus用requestAudioFocus();用完之后,放弃AudioFocus,用abandonAudioFocus()

其中,参数


  • AUDIOFOCUS_GAIN指示申请得到的Audio Focus不知道会持续多久,一般是长期占有;
  • AUDIOFOCUS_GAIN_TRANSIENT指示要申请的AudioFocus是暂时性的,会很快用完释放的;
  • AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK不但说要申请的AudioFocus是暂时性的,还指示当前正在使用AudioFocus的可以继续播放,只是要“duck”一下(降低音量)。


返回值,可能是:



二、AudioFocus被抢占与重新获得

由上节中知道,申请/释放AudioFocus时传入了AudioManager.OnAudioFocusChangeListener这个参数,其onAudioFocusChange()方法是Audio Focus被抢占与再次获得通知的地方。所以,每个要使用AudioFocus的程序都要小心实现这个函数,保证AudioFocus实现的一致性。

onAudioFocusChange()方法的focusChange参数指示了该AudioFocus的竞争者对AudioFocus的拥有情况,取值如下:


  • AUDIOFOCUS_GAIN:获得了Audio Focus;
  • AUDIOFOCUS_LOSS:失去了Audio Focus,并将会持续很长的时间。这里因为可能会停掉很长时间,所以不仅仅要停止Audio的播放,最好直接释放掉Media资源。而因为停止播放Audio的时间会很长,如果程序因为这个原因而失去AudioFocus,最好不要让它再次自动获得AudioFocus而继续播放,不然突然冒出来的声音会让用户感觉莫名其妙,感受很不好。这里直接放弃AudioFocus,当然也不用再侦听远程播放控制【如下面代码的处理】。要再次播放,除非用户再在界面上点击开始播放,才重新初始化Media,进行播放。
  • AUDIOFOCUS_LOSS_TRANSIENT:暂时失去Audio Focus,并会很快再次获得。必须停止Audio的播放,但是因为可能会很快再次获得AudioFocus,这里可以不释放Media资源;
  • AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:暂时失去AudioFocus,但是可以继续播放,不过要在降低音量。


下面是onAudioFocusChange()方法处理的代码片段:

1. er afChangeListener = new OnAudioFocusChangeListener() {  
2.    public void onAudioFocusChange(int focusChange) {  
3.        if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT  
4.            // Pause playback   
5.        } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {  
6.            am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);  
7.            am.abandonAudioFocus(afChangeListener);  
8.            // Stop playback   
9.        } else if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {  
10.            // Lower the volume   
11.        } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {  
12.            // Resume playback or Raise it back to normal   
13.        }  
14.    }  
15.


三、典型的应用AudioFocus的场景

下面的时序图描述了AudioFocus被抢占与再次获取的典型场景:




Android中的Audio播放:竞争Audio…_App


注意为了描述简单,此图中除了两个竞争Audio Focus的App之外,只用AudioManager表征了Android的AudioFocus机制中内部参与的对象,实际AudioManager只是外部的表象,内部参与的对象很多,回调函数也并非简单的直接由AudioManager调用,其中还包含了复杂的IPC机制。

图中:


  • AudioFocus Client通过requestAudioFocus()获取AudioFocus,在获得AudioFocus之后,开始播放Audio[Step#1 ~ #2];
  • 其它程序(Other App)也通过requestAudioFocus()获取同类AudioStream的AudioFocus [Step#3]
  • AudioFocus Client失去了Audio Focus,在onAudioFocusChanged()中,根据focusChange的值,做第二节中的处理[Step#4];
  • 其它程序(Other App)获取Audio Focus之后,开始播放Audio[Step#5];
  • 其它程序(Other App)使用Audio之后,通过abandonAudioFocus()归还AudioFocus [Step#6];
  • AudioFocus Client重新获得了Audio Focus,可做进一步的处理 [Step#7]



小结

Audio Focus机制要参与各方充分理解并统一遵照施行,有没有遵照者或者实现有误的程序存在就可能打破这一机制,带来糟糕的用户体验。在保证Built-in程序没问题的前提下,如果进入AndroidMarket之前的程序都严格执行了AudioFocus相关的测试,应该也没问题。

标签:AUDIOFOCUS,播放,程序,Focus,AudioFocus,Android,Audio
From: https://blog.51cto.com/u_548275/6886112

相关文章

  • android下面res目录使用
    res文件夹里面的多个文件夹的各自介绍(来自网上的Android开发指南中文版内容):  *res/raw和assets的相同点:目录Directory资源类型ResourceTypesres/anim/XML文件,它们被编译进逐帧动画(framebyframeanimation)或补间动画(tweenedanimation)对象res/drawable/.png、.9.png、.......
  • Android实现数据存储技术
    本文介绍Android中的5种数据存储方式。数据存储在开发中是使用最频繁的,在这里主要介绍Android平台中实现数据存储的5种方式,分别是:使用SharedPreferences存储数据; 文件存储数据;SQLite数据库存储数据;使用ContentProvider存储数据;网络存储数据;下面将为大家一一详细介绍。第一种: ......
  • Android处理图片OOM的若干方法小结
    众所周知,每个Android应用程序在运行时都有一定的内存限制,限制大小一般为16MB或24MB(视平台而定)。因此在开发应用时需要特别关注自身的内存使用量,而一般最耗内存量的资源,一般是图片、音频文件、视频文件等多媒体资源;由于Android系统对音频、视频等资源做了边解析便播放的处理,使用时......
  • Android之Widget  Frame…
        2AppWidget Framework2.1定义    (1)AppWidgetService是框架的的核心类,是系统service之一,它负责widgets的管理工作。加载,删除,定时事件等都需要AppWidgetService的处理。开机自启动的。     ......
  • android网络通信之HTTP协议教程实…
    在现在的开发和应用中,网络通讯是必不可少的。虽然还是比较怀念小时候,抱着一台95在那里玩单机游戏玩的天昏地暗的时光,但是,现在,就算一个幼儿园的小盆友如果问你要手机玩游戏,突然发现居然买不了冰激凌草莓果汁什么的去喂talkinggina,或者切出一个超爆的水果分数却传不到网上去炫......
  • Android AIDL——实现机制浅析
    1.基于前面写的aidl使用,这段时间准备研究ActivityManager框架,对aidl进行了更深入的研究,因为android框架大量使用了进程通信机制,所以,在研究androidframework前认真研究一下AIDL的实现机制十分有必要的3.aidl接口packagecom.cao.android.demos.binder.aidl;importcom.cao.an......
  • Android NFC简介
    目录:AndroidNFC1 简介1.1 什么是 NFC1.2Android 上的 NFC1.3Android 中的 NFC 通讯机制2 用法2.1 读取 tag2.2 发送消息2.2.1 发送过程2.2.2NDEF 消息格式1 简介1.1 什么是 NFC近场通讯 (NearFiledCommunication) 技术是一种近距离的高频无线......
  • 【HarmonyOS】ArkTS 组件内转场动画,动画播放时颜色异常问题
    ​【关键字】HarmonyOS、ArkTS、组件内转场动画、颜色异常 【问题描述】根据组件内转场动画文档中示例编写代码,使用动画转场组件button,并给button设置背景色让button透明度为0,实现动画转场时,会先出现默认蓝色button,然后动画再消失,问题代码如下所示:@Stateflag:boolean=t......
  • 【HarmonyOS】ArkTS 组件内转场动画,动画播放时颜色异常问题
    【关键字】HarmonyOS、ArkTS、组件内转场动画、颜色异常【问题描述】根据组件内转场动画文档中示例编写代码,使用动画转场组件button,并给button设置背景色让button透明度为0,实现动画转场时,会先出现默认蓝色button,然后动画再消失,问题代码如下所示:@Stateflag:boolean=true;@State......
  • Android-组件属性
    ImageView:app:tint=“”(tint:染色)作用:将非透明像素点染成指定颜色 EditText:android:selectAllOnFocus="true"作用:输入框获取焦点后,获取到所有文本内容 ......