当前位置:   article > 正文

Android原生Settings源码分析_android 原生setting

android 原生setting

最近要修改Settings相关的东西,就顺便研究下Setings的代码结构,特做个记录

 

由于修改的是Android4.4的平台,所以以下都是在Android4.4基础上分析的。

 

1、入口

从packages/apps/settings/AndroidManifestxml找到Settings模块的入口:

  1. <activity android:name="Settings"
  2. android:label="@string/settings_label_launcher"
  3. android:taskAffinity="com.android.settings"
  4. android:launchMode="singleTask">
  5. <intent-filter>
  6. <action android:name="android.intent.action.MAIN" />
  7. <action android:name="android.settings.SETTINGS" />
  8. <category android:name="android.intent.category.DEFAULT" />
  9. <category android:name="android.intent.category.LAUNCHER" />
  10. </intent-filter>
  11. </activity>


说明进入settings的第一个Activity为Settings.java

 

2、Settings extends PreferenceActivity

settings继承与preverenceActivity,所以我们要主要两个重载函数onBuildHeaders和setListAdapter

1)onBuildHeaders

onbuildHeaders负责加载xml布局文件,这里的xml文件settings_headers使用的是Preference Headers,没有使用传统的PreferenceScreen。

每个Header对应一个子界面,一般为Fragment

关于这点可以参考http://www.xuebuyuan.com/549370.html

  1. @Override
  2. public void onBuildHeaders(List<Header> headers) {
  3. if (!onIsHidingHeaders()) {
  4. loadHeadersFromResource(R.xml.settings_headers, headers);
  5. updateHeaderList(headers);
  6. }
  7. }


 

2)setListAdapter

PreferenceActivity继承于ListActivity,所以这里可以使用需要ListView创建Adapter,这里的自定义Adapter对不同子菜单的分别处理有关键性作用

 

@Override    public void setListAdapter(ListAdapter adapter) {        if (adapter == null) {            super.setListAdapter(null);        } else {            DevicePolicyManager dpm =                    (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);            super.setListAdapter(new HeaderAdapter(this, getHeaders(), mAuthenticatorHelper, dpm));        }    }

 

自定义Adapter:

  1. private static class HeaderAdapter extends ArrayAdapter<Header> {
  2. static final int HEADER_TYPE_CATEGORY = 0;
  3. static final int HEADER_TYPE_NORMAL = 1;
  4. static final int HEADER_TYPE_SWITCH = 2;
  5. static final int HEADER_TYPE_BUTTON = 3;
  6. private static final int HEADER_TYPE_COUNT = HEADER_TYPE_BUTTON + 1;
  7. private final WifiEnabler mWifiEnabler;
  8. private final BluetoothEnabler mBluetoothEnabler;
  9. private AuthenticatorHelper mAuthHelper;
  10. private DevicePolicyManager mDevicePolicyManager;
  11. private static class HeaderViewHolder {
  12. ImageView icon;
  13. TextView title;
  14. TextView summary;
  15. Switch switch_;
  16. ImageButton button_;
  17. View divider_;
  18. }
  19. private LayoutInflater mInflater;
  20. static int getHeaderType(Header header) {
  21. if (header.fragment == null && header.intent == null) {
  22. return HEADER_TYPE_CATEGORY;
  23. } else if (header.id == R.id.security_settings) {
  24. return HEADER_TYPE_BUTTON;
  25. } else {
  26. return HEADER_TYPE_NORMAL;
  27. }
  28. }
  29. @Override
  30. public int getItemViewType(int position) {
  31. Header header = getItem(position);
  32. return getHeaderType(header);
  33. }
  34. @Override
  35. public boolean areAllItemsEnabled() {
  36. return false; // because of categories
  37. }
  38. @Override
  39. public boolean isEnabled(int position) {
  40. return getItemViewType(position) != HEADER_TYPE_CATEGORY;
  41. }
  42. @Override
  43. public int getViewTypeCount() {
  44. return HEADER_TYPE_COUNT;
  45. }
  46. @Override
  47. public boolean hasStableIds() {
  48. return true;
  49. }
  50. public HeaderAdapter(Context context, List<Header> objects,
  51. AuthenticatorHelper authenticatorHelper, DevicePolicyManager dpm) {
  52. super(context, 0, objects);
  53. mAuthHelper = authenticatorHelper;
  54. mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  55. // Temp Switches provided as placeholder until the adapter replaces these with actual
  56. // Switches inflated from their layouts. Must be done before adapter is set in super
  57. mWifiEnabler = new WifiEnabler(context, new Switch(context));
  58. mBluetoothEnabler = new BluetoothEnabler(context, new Switch(context));
  59. mDevicePolicyManager = dpm;
  60. }
  61. @Override
  62. public View getView(int position, View convertView, ViewGroup parent) {
  63. HeaderViewHolder holder;
  64. Header header = getItem(position);
  65. int headerType = getHeaderType(header);
  66. View view = null;
  67. if (convertView == null) {
  68. holder = new HeaderViewHolder();
  69. switch (headerType) {
  70. case HEADER_TYPE_CATEGORY:
  71. view = new TextView(getContext(), null,
  72. android.R.attr.listSeparatorTextViewStyle);
  73. holder.title = (TextView) view;
  74. break;
  75. case HEADER_TYPE_SWITCH:
  76. view = mInflater.inflate(R.layout.preference_header_switch_item, parent,
  77. false);
  78. holder.icon = (ImageView) view.findViewById(R.id.icon);
  79. holder.title = (TextView)
  80. view.findViewById(com.android.internal.R.id.title);
  81. holder.summary = (TextView)
  82. view.findViewById(com.android.internal.R.id.summary);
  83. holder.switch_ = (Switch) view.findViewById(R.id.switchWidget);
  84. break;
  85. case HEADER_TYPE_BUTTON:
  86. view = mInflater.inflate(R.layout.preference_header_button_item, parent,
  87. false);
  88. holder.icon = (ImageView) view.findViewById(R.id.icon);
  89. holder.title = (TextView)
  90. view.findViewById(com.android.internal.R.id.title);
  91. holder.summary = (TextView)
  92. view.findViewById(com.android.internal.R.id.summary);
  93. holder.button_ = (ImageButton) view.findViewById(R.id.buttonWidget);
  94. holder.divider_ = view.findViewById(R.id.divider);
  95. break;
  96. case HEADER_TYPE_NORMAL:
  97. view = mInflater.inflate(
  98. R.layout.preference_header_item, parent,
  99. false);
  100. holder.icon = (ImageView) view.findViewById(R.id.icon);
  101. holder.title = (TextView)
  102. view.findViewById(com.android.internal.R.id.title);
  103. holder.summary = (TextView)
  104. view.findViewById(com.android.internal.R.id.summary);
  105. break;
  106. }
  107. view.setTag(holder);
  108. } else {
  109. view = convertView;
  110. holder = (HeaderViewHolder) view.getTag();
  111. }
  112. // All view fields must be updated every time, because the view may be recycled
  113. switch (headerType) {
  114. case HEADER_TYPE_CATEGORY:
  115. holder.title.setText(header.getTitle(getContext().getResources()));
  116. break;
  117. case HEADER_TYPE_SWITCH:
  118. // Would need a different treatment if the main menu had more switches
  119. if (header.id == R.id.wifi_settings) {
  120. mWifiEnabler.setSwitch(holder.switch_);
  121. } else {
  122. mBluetoothEnabler.setSwitch(holder.switch_);
  123. }
  124. updateCommonHeaderView(header, holder);
  125. break;
  126. case HEADER_TYPE_BUTTON:
  127. if (header.id == R.id.security_settings) {
  128. boolean hasCert = DevicePolicyManager.hasAnyCaCertsInstalled();
  129. if (hasCert) {
  130. holder.button_.setVisibility(View.VISIBLE);
  131. holder.divider_.setVisibility(View.VISIBLE);
  132. boolean isManaged = mDevicePolicyManager.getDeviceOwner() != null;
  133. if (isManaged) {
  134. holder.button_.setImageResource(R.drawable.ic_settings_about);
  135. } else {
  136. holder.button_.setImageResource(
  137. android.R.drawable.stat_notify_error);
  138. }
  139. holder.button_.setOnClickListener(new OnClickListener() {
  140. @Override
  141. public void onClick(View v) {
  142. Intent intent = new Intent(
  143. android.provider.Settings.ACTION_MONITORING_CERT_INFO);
  144. getContext().startActivity(intent);
  145. }
  146. });
  147. } else {
  148. holder.button_.setVisibility(View.GONE);
  149. holder.divider_.setVisibility(View.GONE);
  150. }
  151. }
  152. updateCommonHeaderView(header, holder);
  153. break;
  154. case HEADER_TYPE_NORMAL:
  155. updateCommonHeaderView(header, holder);
  156. break;
  157. }
  158. return view;
  159. }


3、settings设置数据的保存

虽然preference是可以记录状态,并保存在sharedpreference文件中,但是有很多状态值是全局的,比如wifi,蓝牙等。所以这里涉及到全局数据的保存

以蓝牙为例,蓝牙打开关闭的操作在BluetoothEnabler.java里面

当按下蓝牙开关时,调用mLocalAdapter.setBluetoothEnabled(isChecked);-->BluetoothAdapter.enable()-->BluetoothAdapter:mManagerService.enable();-->BluetoothManagerService:enable-->BluetoothManagerService:persistBluetoothSetting

  1. private void persistBluetoothSetting(int value) {
  2. Settings.Global.putInt(mContext.getContentResolver(),
  3. Settings.Global.BLUETOOTH_ON,
  4. value);
  5. }


最终改的是Settings.Global.BLUETOOTH_ON的值,而这个默认值则在DatabaseHelper.java中设置

  1. loadBooleanSetting(stmt, Settings.Global.BLUETOOTH_ON,
  2. R.bool.def_bluetooth_on);


其他的值,比如wifi开关,默认语言等,都类似于这个过程


 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/458045
推荐阅读
相关标签
  

闽ICP备14008679号