AndroidSettings源代码分析


Settings涉及的模块

四个部分:

WIRELESS & NETWORKS   :SIM卡管理,流量使用情况,飞行模式,VPN,网络共享等

DEVICE :  情景模式,显示,存储,电池,应用程序

PERSONAL: 账户与同步,位置服务,安全,语言和输入法,备份和重置

SYSTEM:   日期和时间,定时开关及,辅助功能,开发人员选项,关于手机

 

1.    com.android.settings.Settings类

1)       Framgment机制

 

Fragment是我们在单个Activity上要切换多个UI界面,显示不同内容,对不同的界面不再使用不同的Activity。模块化这些UI面板以便提供给其他Acitivity使用便利。同时我们显示的Fragment也会受到当前的这个 Acitivity生命周期影响。

 

         因为使用了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">

   

       <!-- CustomizationSettings -->

      <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 andNETWORKS -->

    <headerandroid: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

 

2)       实现onBuildHeaders()回调用来指定头文件

 

调用loadHeadersFromResource()方法对界面进行加载

@Override

public void onBuildHeaders(List<Header>headers) {

         loadHeadersFromResource(R.xml.settings_headers,headers);

          updateHeaderList(headers);

         mHeaders = headers;

}

 

3)        显示界面

public voidsetListAdapter(ListAdapter adapter) { 

    if (mHeaders == null){ 

       mHeaders = newArrayList<Header>(); 

       // When the savedstate provides the list of headers, onBuildHeaders is not called 

       // Copy the list ofHeaders from the adapter, preserving their order 

       for (int i = 0; i< adapter.getCount(); i++) { 

         mHeaders.add((Header) adapter.getItem(i)); 

        } 

     } 

    // Ignore the adapterprovided by PreferenceActivity and substitute ours instead 

   super.setListAdapter(newHeaderAdapter(this, mHeaders));

 

HeaderAdapter是Settings中的一个内部类。下面来看下HeaderAdapter这个适配类

private static class HeaderAdapter extends ArrayAdapter<Header>{ 

     //三种 类型的header 

     static final intHEADER_TYPE_CATEGORY = 0;//分类 

     static final intHEADER_TYPE_NORMAL = 1;//一般的 

     static final intHEADER_TYPE_SWITCH = 2;//开关形式的 

     .... 

类的开头就定义了三个常量:这个代表Header的三种类型

HEADER_TYPE_CATEGORY代表一个分类,它不能点击,像这个:

HEADER_TYPE_NORMAL代表一个常规项,像这个:

HEADER_TYPE_SWITCH代表一种开头形式的类型,像这个:

getView()方法中也是根据三种不同的类型,加载不同的view以及数据。

 

4)        处理点击事件

PreferenceActivity重写了ListActivity的这个文法

[java] view plaincopy

@Override 

    protected voidonListItemClick(ListView l, View v, int position, long id) { 

       super.onListItemClick(l, v, position, id); 

        if (mAdapter !=null) { 

            Object item =mAdapter.getItem(position); 

            if (iteminstanceof Header) onHeaderClick((Header) item, position); 

        } 

    } 

再看onHeaderClick()方法

 

public void onHeaderClick(Header header, int position) { 

    if (header.fragment !=null) { 

       if (mSinglePane){ 

           int titleRes =header.breadCrumbTitleRes; 

           int shortTitleRes= header.breadCrumbShortTitleRes; 

            if (titleRes ==0) { 

                titleRes =header.titleRes; 

               shortTitleRes = 0; 

             } 

            startWithFragment(header.fragment,header.fragmentArguments, 

                       null, 0, titleRes, shortTitleRes); 

       } else { 

          switchToHeader(header); 

       } 

     } else if(header.intent != null) { 

       startActivity(header.intent); 

     } 

 } 

2.     获取与设置系统属性

         在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方法。

 

3.     language settings示例分析

通过分析language settings中的auto_caps(自动替换)设置来分析Settings中是怎么对系统属性进行基本设置的。

 

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" />

 

2) 找到 R.xml.language_settings布局文件

     在 InputMethodAndLanguageSettings.java中,我们找到:

                   publicvoid 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"/>

 

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的对象*/

        CheckBoxPreferencechkPref = (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()方法的应用

 

4.    在辅助功能中添加自动生成短信

1)       首先根据setting_header.xml查到辅助功能的属性信息,找到com.android.settings.accessibility.AccessibilitySettings,

 

2)      根据AccessibilitySettings 的oncreate(),找到fragment Accessibility_settings.xml添加

<PreferenceScreen

             android:key="message_auto_insert"

             android:title="@string/message_auto_insert_title"/>

 

3)      在AccessibilitySettings 的onPreferenceTreeClick方法中添加

else if(preference.getKey().equals("message_auto_insert")){ 

Intent intent =new Intent(Intent.ACTION_MAIN);

intent.setClassName("com.huaqin.messageinsert",

"com.huaqin.messageinsert.MainActivity");

try {

startActivity(intent);

} catch (Exception e) {

Log.e(LOG_TAG, "Unable to start activity " + intent.toString());

}

}

注:将自动生成短信的应用activity发布方式改为:DEFAULT,可以隐藏应用,只通过辅助功能去启动。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android系统的源代码是由若干部分组成的,其中包括内核、硬件驱动、库、Android Runtime、应用框架等。这些源代码构成了Android系统的核心部分。 Android系统的内核是基于Linux内核开发的,它负责Android系统的底层管理和资源调度,包括进程管理、内存管理、设备驱动、文件系统等。内核的源代码主要包含在kernel目录下,这部分源代码决定了系统的稳定性和性能。 硬件驱动部分负责与硬件设备的交互,包括音频、摄像头、蓝牙、WiFi等模块的驱动程序。这些驱动程序的源代码主要包含在硬件供应商提供的内核模块中,并在Android系统中进行定制和适配。 库部分包含一些常用的功能模块,例如图形库、网络库、数据库等,这些库提供了丰富的API接口,方便应用程序的开发。这部分源代码主要包含在frameworks目录下。 Android Runtime是一个虚拟机环境,负责运行Android应用程序。它主要由Dalvik或者使用了ART(Android RunTime)的ART虚拟机构成。Dalvik虚拟机的源代码包含在dalvik目录下,而ART虚拟机的源代码则包含在art目录下。这些源代码决定了Android应用程序的性能和运行效果。 应用框架是Android系统的核心,它提供了许多系统级服务、管理机制和应用程序运行环境。应用框架的源代码包含在frameworks目录下的base目录中,这部分源代码负责协调各个模块之间的交互和通信。 总之,Android系统的源代码部分包含了内核、硬件驱动、库、Android Runtime和应用框架等关键组成部分,这些源代码共同构建了Android系统的功能和特性。对于Android开发者来说,深入了解源代码可以更好地理解Android系统的工作原理,并在应用开发过程中进行定制和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值