Settings模块
第一部分 Settings涉及的模块
4.0设置的layout有很大的改变。将设置分为四个部分:
WIRELESS & NETWORKS :SIM卡管理,流量使用情况,飞行模式,VPN,网络共享等
DEVICE : 情景模式,显示,存储,电池,应用程序
PERSONAL: 账户与同步,位置服务,安全,语言和输入法,备份和重置
SYSTEM: 日期和时间,定时开关及,辅助功能,开发人员选项,关于手机
第二部分 Fragment
2.1 com.android.settings.Settings类
设置页面的Activity:
public class Settings extends PreferenceActivity implements ButtonBarHandler{}。因为从3.0中就引入了Fragment机制,所以在Settings里面就只有这一个(待确定)Acitivity类,而进入里表中的某项设置后,不是进入到新的Activity,而是在原来的Activity上切换了一个UI界面而已。
2.2 Settings模块的Fragment
4.0上Settings使用了Framgment机制。Fragment是我们在单个Activity上要切换多 个UI界面,显示不同内容,对不同的界面不再使用不同的Activity。模块化这些UI面板以便提供给其他Acitivity使用便利。同时我们显示的Fragment也会受到当前的这个 Acitivity生命周期影响。(而平常的Fragment有其自己的生命周期)。
因为使用了Fragment机制,所有Settings的主要的Layout文件和2.3已经有很大不同。在res/xml/settings_headers.xml中可以找到settings中包含的选项,可以比较一下两者的不同:在2.3中layout文件为:(res/xml/settings.xml)<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:title="@string/settings_label"
android:key="parent">
<!-- Customization Settings -->
<com.android.settings.IconPreferenceScreen
android:key="customization_settings"
android:title="@string/customization"
settings:icon="@drawable/ic_settings_customization">
</com.android.settings.IconPreferenceScreen>
...(以下略)
而在4.0中的layout文件为:
<preference-headers
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- WIRELESS and NETWORKS -->
<header android:title="@string/header_category_wireless_networks" />
<!-- Sim management -->
<header
android:id="@+id/sim_settings"
android:icon="@drawable/ic_settings_dualsim"
android:fragment="com.android.settings.gemini.SimManagement"
android:title="@string/gemini_sim_management_title" />
两者的很大的不同就是在4.0中用了Fragment机制后,每个列表相应后不是重新启动一个Activity,而是在原来的Activity(Settings)上切换了一个UI界面,在<header …/>中通过以下方法指定每个模块设置相关的类: android:fragment="com.android.settings.****.****"
这些类都是继承自Fragment类。相关的模块设置的入口类如下:
SIM卡设置:
com.android.settings.gemini.SimManagement
wifi设置:
com.android.settings.wifi.WifiSettings
蓝牙设置:
com.android.settings.bluetooth.BluetoothSettings
流量:
com.android.settings.DataUsageSummary
更多(wireless):
com.android.settings.WirelessSettings
情景模式:
com.android.settings.audioprofile.AudioProfileSettings
显示:
com.android.settings.DisplaySettings
存储:
com.android.settings.deviceinfo.Memory
电池:
com.android.settings.fuelgauge.PowerUsageSummary
应用程序:
com.android.settings.applications.ManageApplications
账户与同步:
com.android.settings.accounts.ManageAccountsSettings
位置:
com.android.settings.LocationSettings
安全:
com.android.settings.SecuritySettings
输入法与语言:
com.android.settings.inputmethod.InputMethodAndLanguageSettings
日期时间设置:
com.android.settings.DateTimeSettings
定时开关机:
com.android.settings.schpwronoff.AlarmClock
开发人员选项:
com.android.settings.DevelopmentSettings
关于手机:
com.android.settings.DeviceInfoSettings
(关于Fragment的相关待补充)
第三部分 获取与设置系统属性
在android中,许多的系统属性都在settings应用当中进行设置的,如wifi,蓝牙状态,本机语言,屏幕亮度等一些相关的系统属性值。这些数据存储在数据库中,对应的两个主要的URI:content://settings/system和 content://settings/secure。
在settings应用中所获取或者修改属性都是调用了framework中的android.provider.settings中的Settings类对应的方法。在android.provider.settings.Settings里面,包含了System和Secure几个内部类,每个内部类对应了一张数据库表,也就是继承自BaseColumn类。System和Secure类分别对应着system和secure数据库表。里面包含了获取设置值的方法以及相关设置项的URI字串。
常见的获取和设置系统属性的方法有:
getString(param1,param2) <---> putString(param1,param2)
getInt(param1,param2) <---> putInt(param1,param2)
getLong(param1,param2) <---> putLong(param1,param2)
getConfiguration(param1,param2) <---> putConfiguration(param1,param2)
getFloat(param1,param2) <---> putFloat(param1,param2)
...
Example:settings应用中是如何对系统属性进行设置的。
当需要获得当前wifi状态的值,调用已封装的方法如下:
Settings.Secure.getInt(getContentResolver() , Settings.Secure.WIFI_ON);
修改wifi状态只需要调用对应的setInt方法就可以实现。
当需要获得当前时间日期自动获取,调用如下:
Settings.System.getInt(getContentResolver() , "auto_time");
修改也是调用对应的setInt方法。
第四部分 language settings示例分析
我们通过分析 language settings中的 auto_caps(自动替换)设置来分析Settings中是怎么对系统属性进行基本设置的.
4.1 找到对应的JAVA类文件 InputMethodAndLanguageSettings
在 res./xml/settings_headers.xml中有:
< !-- Language -->
<header
android:id="@+id/language_settings"
android:fragment="com.android.settings.inputmethod.InputMethodAndLanguageSettings"
android:icon="@drawable/ic_settings_language"
android:title="@string/language_settings" />
根据fragment的定义我们找到:
4.2 找到 R.xml.language_settings布局文件
在 InputMethodAndLanguageSettings.java中,我们找到:
...
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
addPreferencesFromResource(R.xml.language_settings);
…
}
…
可以找到language_settings.xml文件.同样可以看到这里利用了Fragment机制。
在代码中我们找到自动替换的设置选项分析:
<CheckBoxPreference
android:key="auto_caps"
android:title="@string/auto_caps"
android:summaryOn="@string/auto_caps_summary"
android:summaryOff="@string/auto_caps_summary"
android:persistent="false"/>
对应的手机中的UI界面为:
4.3 获取和设置属性
在 com.android.settings.inputmethod.InputMethodAndLanguageSettings.java中:
在以下代码获得auto_replace的checkbox的key值:
private static final String[] sHardKeyboardKeys = {
"auto_replace", "auto_caps", "auto_punctuate",
};
在onResume()中来初始化checkbox:四个循环分别为物理键盘的checkbox选项:
// Hard keyboard
if (mHaveHardKeyboard) {
for (int i = 0; i < sHardKeyboardKeys.length; ++i) {
/*以下获取Checkbox的对象*/
CheckBoxPreference chkPref = (CheckBoxPreference)
mHardKeyboardCategory.findPreference(sHardKeyboardKeys[i]);
/*利用Settings.System.getInt()来获取属性值*/
chkPref.setChecked(
System.getInt(getContentResolver(), sSystemSettingNames[i], 1) > 0);
}
}
我们可以看到Settings.System.getInt()方法的应用。
在onPreferenceClick()中可以看到对auto_cap选项的设置:
if (mHaveHardKeyboard) {
for (int i = 0; i < sHardKeyboardKeys.length; ++i) {
if (chkPref == mHardKeyboardCategory.findPreference(sHardKeyboardKeys[i])) {
/*将设置的新的属性写如数据库*/
System.putInt(getContentResolver(), sSystemSettingNames[i],
chkPref.isChecked() ? 1 : 0);
return true;
}
}
}
我们可以看到Settings.System.putInt()方法的应用。
通过以上步骤,我们可以详细地明白Settings是怎么获取与设置系统的属性的。