最近一个项目过认证, 在声压测试时failed。整改方案为:在用户将耳机音量提高至安全音量以上时,阻止此操作并弹出警告框,待用户确认后才提升音量。一开始并不知道android4.2中默认自带了这套机制,于是自己瞎琢磨添加了一套机制:在Audioervice中监听插入耳机时的音量变化,发送广播到SystemUI,再在SystemUI中注册Receiver去判断是否需要弹出警告框。历经千辛万苦终于把流程可以跑通,功能也可以实现,但有一个小BUG,就是用户当前提升的音量超过了安全音量,弹出警告框的同时音量也已经完成调节动作,不符合整改方案的要求。后来,无意中看到AudioService中有SafeVolume之类的变量,才恍然大悟,原来android默认就支持这个功能,于是将之前瞎琢磨的那套怒而删之,仔细研究如何开启android默认的机制, 以下是小小的心得,特此记录。
----------------------------------------------------------------------------------------------------
代码位置:frameworks/base/media/java/android/media/AudioService.java
public AudioService(Context context) {
.......... //省略
mSafeMediaVolumeState = new Integer(Settings.Global.getInt(mContentResolver,Settings.Global.AUDIO_SAFE_VOLUME_STATE,SAFE_MEDIA_VOLUME_NOT_CONFIGURED));
mSafeMediaVolumeIndex = mContext.getResources().getInteger(com.android.internal.R.integer.config_safe_media_volume_index) * 10;
.......... //省略
}
在AudioService的构造函数中,有关于安全音量的初始化设置,从配置文件中读取是否配置安全媒体音量以及安全音量的大小。
是否enable的配置文件在frameworks/base/core/res/res/values-Mcc码 文件夹中:
<!-- Whether safe headphone volume is enabled or not (country specific). -->
<bool name="config_safe_media_volume_enabled">true</bool>
goole了一下,中国的mcc码值为460, mnc为00或者01(对应移动或者联通), 我的这套android代码中没有这个文件夹, 我自己创建了一个并赋值。
配置安全媒体音量大小的文件在:frameworks/base/core/res/res/values/Config.xml中:
<!-- Safe headphone volume index. When music stream volume is below this index the SPL on headphone output is compliant to EN 60950 requirements for portable music players. -->
<integer name="config_safe_media_volume_index">5</integer>
这个index的大小可以根据实际情况进行调整。
再次编译烧录,插入耳机播放音乐,调整音量至第五个梯度时,弹出警告框。
接下来研究这套机制的具体实现流程:
还是刚才的frameworks/base/media/java/android/media/AudioService.java构造方法:
public AudioService(Context context) {
................. //省略
IntentFilter intentFilter = .....;
intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
.................. //省略
context.registerReceiver(mReceiver, intentFilter);
}
AudioService的构造方法中监听BOOT_COMPLETED事件,当机器BOOT完成后,做如下操作:
private class AudioServiceBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
..................
} else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
................
sendMsg(mAudioHandler, MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED, SENDM