最近项目需要修改 Android 7.1 中 Settings 中 OtherSound 子菜单中各项的默认值,并将其隐藏,在此做下整理。
更改默认值
目标
OtherSound子菜单中主要有三项,如下所示。系统中默认这三项为开启的,根据项目要求需将其默认值改为关闭状态。
Charging sounds
Lockscreen sounds
Touch sounds
做法
(1) 修改 Lockscreen sounds 和 Touch sounds两项的默认值
修改文件:\frameworks\base\packages\SettingsProvider\res\values\defaults.xml
<integer name="def_lockscreen_sounds_enabled">0</integer> // Lockscreen sounds 默认值
...
<bool name="def_sound_effects_enabled">false</bool> // Touch sounds 默认值
(2) 修改 Charging sounds 默认值
修改文件:
\packages\apps\Settings\src\com\android\settings\notification\OtherSoundSetting.java
private static final int DEFAULT_OFF = 0; // 新增变量
...
private static final SettingPref PREF_CHARGING_SOUNDS = new SettingPref(
TYPE_GLOBAL, KEY_CHARGING_SOUNDS, Global.CHARGING_SOUNDS_ENABLED, DEFAULT_OFF); // 修改最后一个参数为 DEFAULT_OFF
分析
(1) 与 OtherSound选项中默认值设置直接相关的代码文件是 OtherSoundSettings.java。其相关代码如下
private static final int DEFAULT_ON = 1; // 定义各项的默认值
...
private static final SettingPref PREF_SCREEN_LOCKING_SOUNDS = new SettingPref(
TYPE_SYSTEM, KEY_SCREEN_LOCKING_SOUNDS, System.LOCKSCREEN_SOUNDS_ENABLED, DEFAULT_ON);
private static final SettingPref PREF_CHARGING_SOUNDS = new SettingPref(
TYPE_GLOBAL, KEY_CHARGING_SOUNDS, Global.CHARGING_SOUNDS_ENABLED, DEFAULT_ON);
private static final SettingPref PREF_TOUCH_SOUNDS = new SettingPref(
TYPE_SYSTEM, KEY_TOUCH_SOUNDS, System.SOUND_EFFECTS_ENABLED, DEFAULT_ON) {
@Override
protected boolean setSetting(final Context context, final int value) {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
final AudioManager am =
(AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
if (value != 0) {
am.loadSoundEffects();
} else {
am.unloadSoundEffects();
}
}
});
return super.setSetting(context, value);
}
};
由以上代码可知,各项对应的使能变量如下表
菜单项 使能变量
Charging sounds Global.CHARGING_SOUNDS_ENABLED
Lockscreen sounds System.LOCKSCREEN_SOUNDS_ENABLED
Touch sounds System.SOUND_EFFECTS_ENABLED
(2) 由上可知,各项的值设置是由类 SettingPref 来完成的,SettingsPref.java(该文件与OtherSoundSettings.java 在同个目录下)的相关代码如下
// 构造函数
public SettingPref(int type, String key, String setting, int def, int... values) {
mType = type; // Global 或 System,默认值获取的位置
mKey = key; // 子项键名
mSetting = setting; // 设置标识
mDefault = def; // 默认值
mValues = values;
mUri = getUriFor(mType, mSetting);
}
// 从系统获取子项的值并更新 UI
public void update(Context context) {
final int val = getInt(mType, context.getContentResolver(), mSetting, mDefault);
if (mTwoState != null) {
mTwoState.setChecked(val != 0);
} else if (mDropDown != null) {
mDropDown.setValue(Integer.toString(val));
}
}
// 获取选项的值
protected static int getInt(int type, ContentResolver cr, String setting, int def) {
switch(type) {
case TYPE_GLOBAL:
return Global.getInt(cr, setting, def);
case TYPE_SYSTEM:
return System.getInt(cr, setting, def);
}
throw new IllegalArgumentException();
}
从以上可知,子项的值是通过 Global.getInt 或 System.getInt 获取的,即从数据库获取,若数据库的值为空,则将值设为 def
(3) 修改数据库中相关项的值,相关的文件分别为 DatabaseHelper.java 和 defaults.xml
文件位置:
\frameworks\base\packages\SettingsProvider\res\values\defaults.xml
\frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.java
// 在 DatabaseHelper.java 中寻找各项在配置文件中的 id
loadIntegerSetting(stmt, Settings.System.LOCKSCREEN_SOUNDS_ENABLED,
R.integer.def_lockscreen_sounds_enabled); // 由此可知 lockscreen sounds 在配置文件中的id 为 def_lockscreen_sounds_enabled
loadBooleanSetting(stmt, Settings.System.SOUND_EFFECTS_ENABLED,
R.bool.def_sound_effects_enabled); // 由此可知 touch sounds 在配置文件中的id 为 def_sound_effects_enabled
<!-- 修改 defaults.xml -->
<!-- Default for UI lockscreen sounds enabled-->
<integer name="def_lockscreen_sounds_enabled">0</integer>
<!-- Default for UI touch sounds enabled-->
<bool name="def_sound_effects_enabled">false</bool>
以上修改便可以完成 lockscreen sounds 和 touch sounds 默认值的修改。
(4) 因 charging sounds 的默认值并没有在 defaults.xml 中设置,通过 getInt 中获取的是 def 变量的值,因此要修改 charging sounds,只需定义变量 DEFAULT_OFF=0,并将该变量传入 SettingPref 的构造器中即可完成更改。
隐藏 OtherSound
OtherSound 位于 Sound 菜单下,将其的隐藏只需在 SoundSetting.java 中将其移除就好。
// 添加变量
private static final String KEY_OTHER_SOUNDS = "other_sounds";
// 在 OnCreate中将其移除
removePreference(KEY_OTHER_SOUNDS);