近期要匹配部分第三方应用到系统中,但是涉及到音频部分还存在逻辑的BUG。因此重点关注了下音频管理的部分代码,写一部分目前已经理解的部分。
首先要先阐述下为什么会做现在的工作,起因就是系统中已经有了要调用声音的应用,所以同时再运行另外的需要用到声音的应用时必须要有一个优先级来约束这些声音的音量大小及先后顺序。因此需要对这部分音频管理做逻辑上的处理,使其能协调的发出声音而不是产生声音的重叠和混乱。
查看了FrameWork的代码即SDK文档,最终定位在如下路径的源码中
/frameworks/base/media/java/android/media/AudioManager.java
/frameworks/base/media/java/android/media/AudioService.java
因为初次接触很多只是学习框架的时候了解了下并未仔细看过源码,此次就需要仔细的看了。
查资料得知,在AudioManager中,Android2.2之前的版本是不存在多个程序同时竞争Audio资源的机制的,因此可能在那个版本前音频的管理应该是仅限于音量大小的调整,而不存在竞争互斥优先级高低之分的。
所以先从简单的声音调节入手来分析。
先看一部分代码中的定义:
/** The audio stream for phone calls */ public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_CALL; /** The audio stream for system sounds */ public static final int STREAM_SYSTEM = AudioSystem.STREAM_SYSTEM; /** The audio stream for the phone ring */ public static final int STREAM_RING = AudioSystem.STREAM_RING; /** The audio stream for music playback */ public static final int STREAM_MUSIC = AudioSystem.STREAM_MUSIC; /** The audio stream for alarms */ public static final int STREAM_ALARM = AudioSystem.STREAM_ALARM; /** The audio stream for notifications */ public static final int STREAM_NOTIFICATION = AudioSystem.STREAM_NOTIFICATION; /** @hide The audio stream for phone calls when connected to bluetooth */ public static final int STREAM_BLUETOOTH_SCO = AudioSystem.STREAM_BLUETOOTH_SCO; /** @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */ public static final int STREAM_SYSTEM_ENFORCED = AudioSystem.STREAM_SYSTEM_ENFORCED; /** The audio stream for DTMF Tones */ public static final int STREAM_DTMF = AudioSystem.STREAM_DTMF; /** @hide The audio stream for text to speech (TTS) */ public static final int STREAM_TTS = AudioSystem.STREAM_TTS; /** Number of audio streams */
再看一段调节音量的代码
private AudioManager mAudioManager; mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); mAudioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, AudioManager.FX_FOCUS_NAVIGATION_UP);
上面这部分代码是调整音乐的音量的部分代码,实现效果为按步长1来做声音增大,并且此时调用会出现系统音量条的变化,此操作后续会分析。
现在重点分析函数adjustStreamVolume(int streamType,int direction,int flags)
参数streamType:这部分参数就是最开始定义过的,有STREAM_VOICE_CALL-- 通话,STREAM_SYSTEM -- 系统音量, STREAM_RING -- 铃声
STREAM_MUSIC -- 音乐, STREAM_ALARM -- 闹钟 , STREAM_NOTIFICATION -- 通知, STREAM_BLUETOOTH_SCO -- 蓝牙通话,
后三种看起来不经常用,不是很明白。
参数direction: 这部分参数的定义有ADJUST_RAISE -- 增大, ADJUST_LOWER -- 减小, ADJUST_SAME -- 相同,针对ADJUST_SAME这个参数,可以实现一个小用途就是 调用后可弹出系统音量条而不会使音量变化。
参数flags:这部分为标志位,可选。代码中用到的是焦点上移的标志位,具体有什么特殊用途后续会跟进。
另外其他部分声音调节函数有setStreamVolume(int streamType, int index, int flags) ,这个函数跟上个函数的区别就是上个函数是按步进进行调节,这个函数是可以直接给第二个参数直接赋值,指定音量值来设置。不过需要对参数的取值范围进行判定,以免超出有效值范围。
其他相关函数:
getMasterMaxVolume() -- 获取系统主音量的最大值
getMasterVolume() -- 获取系统当前音量值
getLastAudibleMasterVolume() -- 获取系统静音前的有效音量
getMode() -- 获取当前音频模式,如MODE_INVALID -- 无效,MODE_CURRENT -- 当前,NORMAL--普通,RINGTONE -- 铃声,MODE_IN_CALL --接通电话, MODE_IN_COMMUNICATION -- 通话。
getRingMode() -- 获取响铃方式,如RINGER_MODE_SILENT -- 静音,RINGER_MODE_VIBRATE -- 震动,RINGER_MODE_NORMAL -- 正常,RINGER_MODE_MAX-- 正常
getStreamVolume(int streamType) -- 获取当前模式下的音量值
getStreamMaxVolume(int streamType) -- 获取当前最大铃声音量值
上述部分是AudioManager中关于音量调节的部分解析。后续继续关于调节的涉及另外部分的函数解析。