2012-04-11
本文介绍Android系统中Audio里的RingerMode。从使用的角度,只要关注第一节AudioManager中对于RingerMode的接口;后面章节讲解了AudioService中对于RingerMode的内部实现,以及如何改变RingerMode对某一个AudioStream的影响。
一、利用AudioManager使用RingerMode
RingerMode的获取与设置都是通过AudioManager来进行的。通过context.getSystemService(Context.AUDIO_SERVICE)获得AudioService的本地代理,然后通过调用AudioManager的getRingerMode()/setRingerMode()来获取当前的RingerMode或设置RingerMode。
RingerMode有三种:RINGER_MODE_SILENT,RINGER_MODE_VIBRATE和RINGER_MODE_NORMAL。
RingerMode设置之后,会有广播RINGER_MODE_CHANGED_ACTION发出,并且新的RingerMode会被设置在EXTRA_RINGER_MODE里,广播RINGER_MODE_CHANGED_ACTION的接收者时,可以通过Intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE)获得更改过的RingerMode。
二、RingerMode在AudioService中内部实现
AudioManager不过是在本地的一个代理,具体的实现还是在AudioService中。
RingerMode在AudioService中通过mRingerMode记录;永久存储还是在Settings.System中,对应的设置项是MODE_RINGER,可通过Settings.System.getInt()/putInt()来操作。
《Android中的Audio播放:音量和远程播放控制》中描述的AudioStream是AndroidAudio系统的基础。因为设置RingerMode时,主要牵涉到静音操作,而Android的Audio音量和静音是按照AudioStream来设定的。
看AudioService中关于如何设置RingerMode的[方法setRingerModeInt()的实现]:
三、配置RingerMode对特定AudioStream的影响
前节中讲到,某一个AudioStream是否受设置RingerMode影响是由mRingerModeAffectedStreams决定的,也就是即便设置RingerMode为静音/震动模式(RINGER_MODE_SILENT/RINGER_MODE_VIBRATE)之后, 某个AudioStream还不一定被设置为静音,而是否起作用,关键取决于mRingerModeAffectedStreams上对应于该AudioStream的位上取值。
mRingerModeAffectedStreams在AudioService中初始值是通过Settings.System.getInt(MODE_RINGER_STREAMS_AFFECTED, defVal)获取的
可以看到,默认有四个AudioStream是受RingerMode设置的影响的。
这样,可以通过设置Settings.System.MODE_RINGER_STREAMS_AFFECTED来改变受RingerMode设置影响的AudioStream。
比如,Alarm的“静音模式下是否闹铃”的设置就是通过对AudioStreamSTREAM_ALARM的置位/去位实现的:
一旦MODE_RINGER_STREAMS.AFFECTED被改变,AudioService中会重新获取并更新mRingerModeMutedStreams的值,并再通过setRingerModeInt()设置mRingerModeMutedStreams改变后的RingerMode。
AudioService中通过SettingObserver(继承ContentObserver)在侦听这个设置项的改变而实现的。
总结