Android Settings模块分析

时间:2024-03-05 17:00:45
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是怎么获取与设置系统的属性的。