一、安全音量提醒框的开启
二、修改安全音量提醒框显示
三、重启后还会显示安全音量提醒框
四、一些关于安全音量的初始值
一、安全音量提醒框的开启
安卓系统是有耳机音量保护机制的,对于一些出口欧盟的手机来说,这个提醒是必须存在的。当然安卓系统也是有这个功能的。我们下面就来简单介绍一下
frameworks/base/services/core/java/com/android/server/audio/AudioService.java
private void onConfigureSafeVolume(boolean force, String caller) {
///modify by xiangzaixiansheng for @{
///这个主要是修改下面的布尔值为true;
boolean safeMediaVolumeEnabled =
SystemProperties.getBoolean("audio.safemedia.force", true)
|| mContext.getResources().getBoolean(
com.android.internal.R.bool.config_safe_media_volume_enabled);
///}@
}
对于提醒的安全音量值来说
frameworks/base / core/res/res/values/config.xml
8
true
二、修改安全音量提醒框显示
在安卓原生的逻辑中,达到安全音量后,如果再增加音量,安全音量提醒框会消失。这样其实不太符合欧盟国家的要求。所以简单修改成,用户必须点击确认,才能消失安全音量提醒框。
/frameworks/base/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && mNewVolumeUp
&& (System.currentTimeMillis() - mShowTime) > KEY_CONFIRM_ALLOWED_AFTER) {
if (D.BUG) Log.d(TAG, "Confirmed warning via VOLUME_UP");
//modify by xiangzaixiansheng @{
//mAudioManager.disableSafeMediaVolume();
//dismiss();
///}@
}
return super.onKeyUp(keyCode, event);
}
三、重启后还会显示安全音量提醒框
1: 可以在 AudioService.java 的构造方法中设个变量, 比如 bool bIsFirstBoot = true;
2: 然后在 checkSafeMediaVolume 方法中, 判断此变量, 如下:
frameworks/base/services/core/java/com/android/server/audio/AudioService.java
private boolean checkSafeMediaVolume(int streamType, int index, int device) {
synchronized (mSafeMediaVolumeState) {
//add begin
if(bIsFirstBoot){
mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
bIsFirstBoot = false;
}
//add ends
if ((mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) &&
(mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
((device & mSafeMediaVolumeDevices) != 0) &&
(index > mSafeMediaVolumeIndex)) {
return false;
}
return true;
}
}
四、一些关于安全音量的初始值
public class AudioService extends IAudioService.Stub {
// mSafeMediaVolumeState 当前媒体音量是否被限制的状态标识.
// 设备启动时为 SAFE_MEDIA_VOLUME_NOT_CONFIGURED.
// 根据国家不同或是 SAFE_MEDIA_VOLUME_ACTIVE 或是 SAFE_MEDIA_VOLUME_DISABLED.
// 当用户确认过后会调用 disableSafeMediaVolume() 设为 SAFE_MEDIA_VOLUME_INACTIVE.
private static final int SAFE_MEDIA_VOLUME_NOT_CONFIGURED = 0;
private static final int SAFE_MEDIA_VOLUME_DISABLED = 1;
private static final int SAFE_MEDIA_VOLUME_INACTIVE = 2;
private static final int SAFE_MEDIA_VOLUME_ACTIVE = 3;
private Integer mSafeMediaVolumeState;
// Mobile country code,这里主要用来区分国家
private int mMcc = 0;
// 安全音量值
private int mSafeMediaVolumeIndex;
// mSafeMediaVolumeDevices 强制开启SafeVolume的输出设备(耳机)
private final int mSafeMediaVolumeDevices = AudioSystem.DEVICE_OUT_WIRED_HEADSET |
AudioSystem.DEVICE_OUT_WIRED_HEADPHONE;
// mMusicActiveMs 在禁用SafeVolume下的使用耳机的累计时长.
// 当累计达到 UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX 时会自动开启SafeVolume
private int mMusicActiveMs;
private static final int UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX = (20 * 3600 * 1000); // 20 hours
private static final int MUSIC_ACTIVE_POLL_PERIOD_MS = 60000; // 1 minute polling interval
private static final int SAFE_VOLUME_CONFIGURE_TIMEOUT_MS = 30000; // 30s after boot completed
...
private void onConfigureSafeVolume(boolean force, String caller) {
synchronized (mSafeMediaVolumeState) {
int mcc = mContext.getResources().getConfiguration().mcc;
if ((mMcc != mcc) || ((mMcc == 0) && force)) {
// 从 values 中获取具体的安全音量阈值
mSafeMediaVolumeIndex = mContext.getResources().getInteger(com.android.internal.R.integer.config_safe_media_volume_index) * 10;
boolean safeMediaVolumeEnabled = SystemProperties.getBoolean("audio.safemedia.force", false) || mContext.getResources().getBoolean(com.android.internal.R.bool.config_safe_media_volume_enabled);
boolean safeMediaVolumeBypass = SystemProperties.getBoolean("audio.safemedia.bypass", false);
// persitedSate 只会是 "disabled" 或者 "active",这个变量值作用于下次启动且不能是 "inactive"
int persistedState;
if (safeMediaVolumeEnabled && !safeMediaVolumeBypass) {
persistedState = SAFE_MEDIA_VOLUME_ACTIVE;
// 有可能在这个方法被调用之前用户已经设为"inactive"了.
if (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_INACTIVE) {
if (mMusicActiveMs == 0) {
mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
// 降低音量到安全阈值
enforceSafeMediaVolume(caller);
} else {
// 用户已经过确认
mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE;
}
}
} else {
persistedState = SAFE_MEDIA_VOLUME_DISABLED;
mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED;
}
mMcc = mcc;
// 发送保存 persistedState 的消息
sendMsg(mAudioHandler,
MSG_PERSIST_SAFE_VOLUME_STATE,
SENDMSG_QUEUE,
persistedState,
0,
null,
0);
}
}
}