2.8 RingerMode
2.8.1利用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。
2.8.2 RingerMode在AudioService中内部实现
AudioManager不过是在本地的一个代理〃具体的实现还是在AudioService中。 RingerMode在AudioService中通过mRingerMode记录;永久存储还是在Settings.System中〃对应的设置项是MODE_RINGER〃可通过Settings.System.getInt()/putInt()来操作。
AudioService中RingerMode设置的方法(方法setRingerModeInt()的实现)
private void setRingerModeInt(int ringerMode, boolean persist) { mRingerMode = ringerMode;
// Mute stream if not previously muted by ringer mode and ringer mode
// is not RINGER_MODE_NORMAL and stream is affected by ringer mode. // Unmute stream if previously muted by ringer mode and ringer mode // is RINGER_MODE_NORMAL or stream is not affected by ringer mode. Log.d(TAG, \ + ringerMode); int numStreamTypes = AudioSystem.getNumStreamTypes();
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { if (isStreamMutedByRingerMode(streamType)) {
if (!isStreamAffectedByRingerMode(streamType) ||
ArcherMind Inc. Proprietary – For Internal Use Only
CONFIDENTIAL Date
Page 31 of 33
mRingerMode == AudioManager.RINGER_MODE_NORMAL) { mStreamStates[streamType].mute(null, false);
mRingerModeMutedStreams &= ~(1 << streamType); } } else {
if (isStreamAffectedByRingerMode(streamType) &&
mRingerMode != AudioManager.RINGER_MODE_NORMAL) { mStreamStates[streamType].mute(null, true);
mRingerModeMutedStreams |= (1 << streamType); } } }
改变RingerMode是否影响某一个AudioStream的音量(静音)是由 isStreamAffectedByRingerMode(streamType:int) 决定的〃而该方法是检查mRingerModeAffectedStreams上针对该AudioStream的位上是否被置位〃亦即〃mRingerModeAffectedStreams是AudioStream是否受RingerMode影响的Bitmasks。
如果AudioStream被静音〃则在mRingerModeMutedStreams的相应位上置位做标志。所以mRingerModeMutedStreams是当前AudioStream是否因为RingerMode而静音的Bitmasks。
RingerMode记录在mRingerMode〃但永久存储是通过Settings.System〃所以设置完具体的RingerMode之后〃通过
Settings.System.putInt(cr,Settings.System.MODE_RINGER, mRingerMode)保存当前的RingerMode。
2.8.3 配置RingerMode对特定AudioStream的影响
前节中讲到〃某一个AudioStream是否受设置RingerMode影响是由
mRingerModeAffectedStreams决定的〃也就是即便设置RingerMode为静音/震动模式(RINGER_MODE_SILENT/RINGER_MODE_VIBRATE)之后〃 某个AudioStream还不一定被设置为静音〃而是否起作用〃关键取决于mRingerModeAffectedStreams上对应于该AudioStream的位上取值。
mRingerModeAffectedStreams在AudioService中初始值是通过
Settings.System.getInt(mContentResolver,
ArcherMind Inc. Proprietary – For Internal Use Only
CONFIDENTIAL Date
Page 32 of 33
Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);获取的
mRingerModeAffectedStreams = Settings.System.getInt(cr,
Settings.System.MODE_RINGER_STREAMS_AFFECTED,
((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
(1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)));
可以看到〃默认有四个AudioStream是受RingerMode设置的影响的。
这样〃可以通过设置Settings.System.MODE_RINGER_STREAM_AFFECTED来改变受RingerMode设置影响的AudioStream。
比如〃Alarm的“静音模式下是否闹铃”的设置就是通过对AudioStreamSTREAM_ALARM的置位/去位实现的:
代码位置:packages/apps/DeskClock/src/com/android/deskclock/SettingsActivity.java
int ringerModeStreamTypes = Settings.System.getInt( getContentResolver(),
Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
if (pref.isChecked()) {
ringerModeStreamTypes &= ~ALARM_STREAM_TYPE_BIT; } else {
ringerModeStreamTypes |= ALARM_STREAM_TYPE_BIT; }
Settings.System.putInt(getContentResolver(),
Settings.System.MODE_RINGER_STREAMS_AFFECTED, ringerModeStreamTypes);
ArcherMind Inc. Proprietary – For Internal Use Only
CONFIDENTIAL Date
Page 33 of 33