音频焦点问题

当我们在settings中试听铃声,这时候突然来了一个电话,那么会出现试听铃声和来电铃声同时播放的情况。当然,此情况同样适用于闹钟铃声,媒体音乐播放等。那么怎么解决这个问题呢?这就需要当音频焦点。---》

因为系统中可能会有多个应用程序会播放音频,所以需要考虑他们之间该如何交互,为了避免多个应用程序同时播放音乐,Android 系统使用音频焦点来进行统一管理,即只有获得了音频焦点的应用程序才可以播放音乐。 您的应用程序在开始播放音频文件前,首先应该请求获得音频焦点,并且应该同时注册监听音频焦点的丢失通知,即如果音频焦点被系统或其他的应用程序抢占时,您的应用程序可以做出合适的响应。

首先,我要获取一个音频焦点并管理它。

      private boolean requestFocus() {
        // Request audio focus for playback
        int result = mAudioManager.requestAudioFocus(afChangeListener,
                AudioManager.STREAM_RING,
                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
        return result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
    }

  OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {
        public void onAudioFocusChange(int focusChange) {
            if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT
                    || focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
                // Pause playback
                if (mLocalPlayer !=null && mLocalPlayer.isPlaying()){
                    mLocalPlayer.pause();
                }
            } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
                // Resume playback
                  startLocalPlayer();
            } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
                mAudioManager.abandonAudioFocus(afChangeListener);
                // Stop playback
                if (mLocalPlayer !=null && mLocalPlayer.isPlaying()){
                    mLocalPlayer.stop();
                }
            }
        }
    };

可以很清晰的看见,上面的第一个方法是获取音频焦点,通过requestAudioFocus()来实现。而第二个方法就是对音频焦点进行监听并管理。在这里,要先知道以上几个值的含义:

  • AUDIOFOCUS_GAIN_TRANSIENT:只是短暂获得,一会就释放焦点,比如你只是想发个notification时用下一秒不到的铃声。
  • AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:只是背景获得,之前的音频焦点使用者无需释放焦点给我,我将与其共同使用。
  • AUDIOFOCUS_GAIN:我要求完全获得焦点,其他人需要释放焦点。比如我要播放音乐了,这时就要抢占整个音频焦点。
  • AUDIOFOCUS_LOSS:你会长时间的失去焦点,所以不要指望在短时间内能获得。请结束自己的相关音频工作并做好收尾工作。
  • AUDIOFOCUS_LOSS_TRANSIENT:你会短暂的失去音频焦点,你可以暂停音乐,但不要释放资源,因为你一会就可以夺回焦点并继续使用。

知道了以上几个字段的含义,在对应的状态,我们就能做相应的处理。比如AUDIOFOCUS_LOSS_TRANSIENT短暂失去焦点,我们就暂停我们的音乐。AUDIOFOCUS_LOSS长期失去焦点,就直接停掉音乐。AUDIOFOCUS_GAIN我获取了焦点,那么我就要开始播放音乐了(由于我完全获取了焦点,其他音乐就无法播放了,自然当前就只有一个音乐进行播放)。

获取音频焦点,就要释放音频焦点:(在哪里释放,就看当时的代码吧)

    private void destroyLocalPlayer() {
        if (mLocalPlayer != null) {
            mLocalPlayer.reset();
            mLocalPlayer.release();
            mLocalPlayer = null;
            synchronized (sActiveRingtones) {
                sActiveRingtones.remove(this);
            }
        }
        mAudioManager.abandonAudioFocus(afChangeListener);
    }

在解决这个问题的时候,我选择在每次播放试听铃声时,获取音频焦点(何时获取,也要看当时代码情况):

    private void startLocalPlayer() {
        if (mLocalPlayer == null) {
            return;
        }
        synchronized (sActiveRingtones) {
            sActiveRingtones.add(this);
        }
        mLocalPlayer.setOnCompletionListener(mCompletionListener);
        if(requestFocus()){
            mLocalPlayer.start();
        }
    }

成功获取到焦点,才可以播放当前的试听铃声哦!

时间: 2024-10-12 21:06:07

音频焦点问题的相关文章

【转】解决在Android设备播放音频与其他应用重音的问题,并监听耳机的控制按钮

概述 在安卓开发中免不了需要播放一点音乐了,音频了.但是这时候有别的应用正在播放,这时候就会出现重音的现象,完全影响用户体验,我们的项目就遇上了这样的尴尬,然后查找了一些文档,记录一下: 管理音频焦点 从谷歌开发了解到,这跟音频的焦点又关系,我们可以获取当前音频的焦点来解决问题: 有多个应用程序可能播放音频,重要的是要考虑他们应该如何交互.为了避免每个音乐应用程序同时播放,Android使用音频焦点来控制音频播放 - 只有拥有音频焦点的应用程序才能播放音频. 在您的应用程序开始播放音频之前,应该

运用PDO存储将图片、音频文件存入数据库

在数据库中创建表格的时候,有一个字段为image,用来保存图片,那么其类型就是blob,关于blob,百度百科是这样描述的 BLOB (binary large object),二进制大对象,是一个可以存储二进制文件的容器. 在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型. BLOB是一个大文件,典型的BLOB是一张图片或一个声音文件,由于它们的尺寸,必须使用特殊的方式来处理(例如:上传.下载或者存放到一个数据库). 根据Eric Raymond的说法,处理BLOB的主要思想就是

第五章 音频和视频应用详解(第一篇)

---恢复内容开始--- 5.1处理音频 1.使用<video>元素标记 当前<video>标记支持如下三种格式 Ogg:带有Theora视频编码和vorbis音频的Ogg文件 MPEG4:带有H.264视频编码和Acc音频编码的MPEG4文件 WebM:带有Vp8视频编码和Vorbis音频编码的WebM文件 control:供添加播放.暂停和音量控件 <video>标记允许多个"source"元素,"source元素可以链接不同的视频文件

音频焦点整理

音频焦点总结 参考很多大神们的资料,再次表示感谢, 什么叫音频焦点 (audio focus)? android系统是一个多任务操作系统,因此同一时刻允许许多任务同时工作.但是这对音频类应用来说是个挑战,因为如果多个音频同时播放的话,很多情况下用户体验会相当的差!比如听音乐时,来了个电话,这时你的耳机里就是电话和音乐共同工作,绝对是个悲剧! 为了解决这个问题从android2.2开始引入audio focus的概念.为避免多个音乐 App 在同时请求音频播放的时候发生冲突,Android 平台使

安卓获取多媒体(包括 视频、音频、图片)数据

1.Android中所有的多媒体文件除了存储在物理硬盘上,还会将文件信息(路径.id.类型.)保存到数据库中,这样当我们想要获取这些文件的信息时,就不需要耗时的扫描硬盘,只需要读数据库就可以了.Android平台中称手机终端内存为内部存储空间,称SD卡为外部存储空间.针对内部和外部存储空间中的媒体文件信息是分开管理的,各自有独立的数据库管理.外部存储空间和内部存储空间对应的卷标为"external"和"internal". 2.数据库的数据都会由相应的内容提供者暴露

Android音频开发(6):使用 OpenSL ES API(上)

前面几篇文章介绍了如何在 Java 层,利用 Android 提供的 AudioRecord 采集音频,利用 AudioTrack 播放音频,利用 MediaCodec 来编解码,这些 API 均是 Android 提供的 Java 层 API,无论是采集.播放还是编解码,这些 API 接口都需要将音频数据从 Java 拷贝到 native 层,或者从 native 层拷贝到 Java,如果希望减少拷贝,开发更加高效的 Android 音频应用,则建议使用 Android NDK 提供的 Ope

算法系列之二十三:离散傅立叶变换之音频播放与频谱显示

算法系列之二十三:离散傅立叶变换之音频播放与频谱显示 算法系列之二十三离散傅立叶变换之音频播放与频谱显示 导语 什么是频谱 1 频谱的原理 2 频谱的选择 3 频谱的计算 显示动态频谱 1 实现方法 2 杂项说明 结果展示 导语 频谱和均衡器,几乎是媒体播放程序的必备物件,没有这两个功能的媒体播放程序会被认为不够专业,现在主流的播放器都具备这两个功能,foobar 2000的十八段均衡器就曾经让很多人着迷.在上一篇对离散傅立叶变换介绍的基础上,本篇就进一步介绍一下频谱是怎么回事儿,下一篇继续介绍

基于matlab的音频波形实时采集显示 v0.1

robj = audiorecorder(44100,16,1); %设置采样频率.采样位数.通道数 recordblocking(robj,1); %采集初步数据(1s长度) rdata = getaudiodata(robj); %获取音频数据 plot(rdata); %绘制波形 axis([1,44100,-0.1,0.1]); %设置固定坐标轴 drawnow %刷新显示 n = 100; %设定后续的采样更新次数,n与m可联合计算后续更新时间长度 m = 0.1; %设定更新间隔,m

Android通过意图使用内置的音频播放器

如果实现一个音频文件的播放,那么在应用程序中提供播放音频文件功能的最简单的方式是利用内置的"Music(音乐)"应用程序的功能--即使用系统自带的或已安装好的音乐播放器来播放指定的音频文件. 本例比较简单,下面直接给出源代码: 布局文件activity_main: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http:/