Android AudioManager获取媒体焦点

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

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

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

一、AudioFocus的申请与释放

下面看与AudioFocus的相关的类:

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

其中,参数

返回值,可能是:

二、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. OnAudioFocusChangeListener 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. };

==========================================================================

FROM: http://www.linuxidc.com/Linux/2012-04/57902.htm

时间: 2024-10-05 13:07:17

Android AudioManager获取媒体焦点的相关文章

android 中获取当前焦点所在屏幕中的位置 view.getLocationOnScreen(location)

  View view = getCurrentFocus();//获得当前焦点所在的view. Java代码 final int[] location = new int[2]; view.getLocationOnScreen(location); [java] view plaincopy final int[] location = new int[2]; view.getLocationOnScreen(location); 这样就可以得到该视图在全局坐标系中的x,y值,(注意这个值是

Android EditText 获取到焦点

1.第一种方式  这种方式点击输入框不能打开软键盘,点击第二次才可以打开 失去焦点 editText.setFocusable(false); 获取焦点 editText.setFocusable(ture); editText.setFocusableInTouchMode(true); editText.requestFocus(); 2.第一种方式 失去焦点 editText.clearFocus(); 获取焦点 editText.requestFocus(); 版权声明:本文为博主原创文

Android之使用MediaMetadataRetriever类获取媒体信息

一.昨天.介绍了使用MediaMetadataRetriever类来获取视频第一帧:http://blog.csdn.net/u012561176/article/details/47858099,今天,来介绍一下使用MediaMetadataRetriever类获取媒体信息. ??1.当中用到了MediaMetadataRetriever类的无參构造函数:MediaMetadataRetriever() 2.当中用到了MediaMetadataRetriever类的一些经常用法:setData

【Android开发经验】如何获取媒体库中所有音频文件信息,并在文件增删后及时更新媒体库(转)

转载请注明出处: http://blog.csdn.net/zhaokaiqiang1992 今天一打开博客,发现一位朋友给我发了一封私信,请教下面的问题,所以特写此文章,为其解惑. 从这位朋友的提问中,我们需要了解下面的这些问题,才能给他很好的解答: (1)如何获取手机里所有歌曲的信息? (2)在歌曲文件发生改变,比如增删操作之后,如何及时的更新媒体库,从而获取到最新的歌曲信息? (3)在4.4版本之后,扫描sd卡,更新媒体库的操作发生变化了吗? 下面,我将就以上三个问题,进行解答. (1)如

Android 事件传递与焦点处理(tv)

1.概述 上节介绍了android tv app 与android mobile app 的一些表现形式的不同.在实际编程中需要很多的焦点处理,而焦点处理有经常是在事件传递函数内处理的.所以本节做个android 事件传递与焦点处理的小结.另既然描述到android事件传递不可避免就涉及到了android手势拦截.这也是对原有知识认识的一个补充,因为之前涉及到安卓事件传递就是为了做手势拦截,以至于当看到代码在手势分发函数里处理tv的焦点,与界面移动填充时.一时有点迷糊,为什么是写在dispath

android 中获取视频文件的缩略图(非原创)

在android中获取视频文件的缩略图有三种方法: 1.从媒体库中查询 2. android 2.2以后使用ThumbnailUtils类获取 3.调用jni文件,实现MediaMetadataRetriever类 三种方法各有利弊 第一种方法,新视频增加后需要SDCard重新扫描才能给新增加的文件添加缩略图,灵活性差,而且不是很稳定,适合简单应用 第二种方法,实现简单,但2.2以前的版本不支持 第三种方法,实现复杂,但比较灵活,推荐使用 下面给出三种方法的Demo 1.第一种方法: publi

Android如何获取SIM卡信息

android 获取sim卡运营商信息 TelephonyManager tm = (TelephonyManager)Context.getSystemService(Context.TELEPHONY_SERVICE); TelephonyManager 的使用 TelephonyManager 提供设备上获取通讯服务信息的入口,应用程序使用这个类的方法来获取电话的服务商或者状态.程序也可以注册一个监听器来监听电话状态的改变. 不需要直接实例化这个类,使用Context.getSystemS

Android如何获取系统高度、标题栏和状态栏高度

在android应用中,有时需要计算个View的位置,导致需要计算状态栏高度,标题栏高度等信息.为以后方便,在此做个简单记录. 晒代码前先了解一下android屏幕区域的划分,如下图(该图引用自此文http://www.iteye.com/topic/828830 ) 1. 屏幕区域的获取 [java] view plaincopy activity.getWindowManager().getDefaultDisplay(); 2.应用区域的获取 [java] view plaincopy R

Android笔记:获取url或uri字符串中的参数值

d Uri.parse(mArgUrl).getQueryParameter("id") Android笔记:获取url或uri字符串中的参数值