Android 4.4 系统的设置源码阅读记录
———-2014-7-3——————
AndroidManifest.xml
launch的activity是Settings,另外有40多个activity继承于它,比如设置的一级菜单: wifi,蓝牙,声音,显示,安全,应用程序,语言和时间,关于设备等等。实际上都是这一个acitivy。
这里从安全设置看起,SecuritySettings.java
以资源文件R.xml.security_settings_*填充【根据当前锁屏方式,拥有者信息,密码显示等具体情形,加载不同的资源或配置】,具体在createPreferenceHierarchy() 和 onResume中
以改锁屏方式为主线,点击锁屏项时,onPreferenceTreeClick调用,
key值为KEY_UNLOCK_SET_OR_CHANGE,则转到了fragment — “com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment"中()(未知源-preference为mToggleAppInstallation,则setNonMarketAppsAllowed为false或对话框提示,确认后设true; 最终修改了Settings.Global.INSTALL_NON_MARKET_APPS的值enabled ? 1 : 0)。值存储在了setting provider中,目录/data/data/com.android.providers.settings/的db文件,表secure的install_non_market_apps字段。
ChooseLockGeneric中的ChooseLockGenericFragment
onCreate中updatePreferencesOrFinish()加载资源R.xml.security_settings_picker,含汗锁屏方式:无,滑动,人脸解锁,图案,PIN,密码6中方式。
选择一种方式后,执行updateUnlockMethodAndFinish(方式,启用锁屏?),以图案方式为例,启动activity–ChooseLockPattern
ChooseLockPattern
这里它应内含其Fragment–ChooseLockPatternFragment,但没看明白它怎么add上的(填充到activity)。
onCreateView中加载资源R.layout.choose_lock_pattern, onClick中,根据mUiStage状态和click的按钮(继续还是取消),做不同的回馈。 最终确认后执行saveChosenPatternAndFinish()保存密码,修改锁屏方式。
LockPatternUtils.saveLockPattern(密码,isFallback)
LockPatternUtils.setLockPatternEnabled(true);
其中用到了一些内部的API,例如com.android.internal.widget.LockPatternUtils,和@hide的API类似,都是仅系统应用可使用的API。
非系统应用使用则需要通过一些特殊方法才能使用,例如,反射,可参见:
2014-7-4/5————————
Settings的一级菜单:
1 Settings.java
com.android.settings.Settings这个PreferenceActivity在onCreate()中调用onBuildHeaders(),此方法是重点,用来加载设置的一级菜单的:加载资源子R.xml.settings_headers,然后调用updateHeaderList()进行一定的过滤,若设备不支持wifi则去除wifi的header,(使用packagemanger的hasSystemFeature()检测是否支持某功能/特性—wifi,蓝牙,NFC);开发者选项的显示则根据它的sharedPreference的值来确定是否显示。
内部的HeaderAdapter 是Settings的list的adapter,(Settings重写了setListAdapter()设置了HeaderAdapter为ListActivity的adapter),先看wifi项,HeaderAdapter成员mWifiEnabler是WifiEnabler的实例,
2WifiEnabler
com.android.settings.wifi.WifiEnabler主要用来开关wifi,并监视wifi状态以更新switch组件。在其初始化时new一个BroadcastReceiver mReceiver,并在onResume时注册,在onPause时注销。监听3个action:
WIFI_STATE_CHANGED_ACTION,SUPPLICANT_STATE_CHANGED_ACTION,NETWORK_STATE_CHANGED_ACTION,在wifi状态改变时,调用handleWifiStateChanged()来更新switch组件状态;而另外2个action则调用了handleStateChanged()而此方法现在内容为空。开关wifi:onCheckedChanged()中调用WifiManager.setWifiEnabled(boolean)进行开关
3BluetoothEnabler
com.android.settings.bluetooth.BluetoothEnabler 和WiFiEnabler类似,用来开关蓝牙,监视蓝牙状态并更新switch组件。同样的 remuse时注册了ACTION_STATE_CHANGED,pause时注销;使用handleStateChanged()更新switch组件的状态;开关蓝牙:使用LocalBluetoothAdapter.setBluetoothEnabled(boolean),实际上是BluetoothAdapter.enable()和disable()
2014-7-7wifi设置–二级菜单设置的R.xml.settings_headers资源布局了设置的内容,其中第一项为wifi,其中指明 header的fragment :com.android.settings.wifi.WifiSettings,Scanner 一个主线程的handler,在resume期间每个10s进行一次wifi扫描。mReceiver 监听wifi相关的8中action,并做相应的处理。调用handleEvent(context,intent),根据intent进行更新wifi状态、刷新AP列表、更新连接状态等操作。mSetupWizardMode标示是否是第一次启动,首次启动设备连接wifi时亦在这里onActivityCreated()中获取wifiManager等;初始化3种wifi操作的结果监听,连接、保存、忘记,用来操作结果失败时给用户一个Toast提示操作失败;在非mSetupWizardMode时,添加Switch组件(右上角的切换开关)到actionbar,并和WifiEnabler(wifi开关和监视器)关联,注册长按事件registerForContextMenu()onResume() fragment可见时,启用WifiEnabler,注册mReceiver,刷新wifi–AccessPoint(AP)列表;onPause() 焦点不在此fragment时,禁用WifiEnable,注销mReceiver,停止Scanner;刷新wifi列表updateAccessPoints(),在wifi可用时,通过constructAccessPoints()获取AccessPoint集合并依次add到preference中,而constructAccessPoints()是通过WifiManager的getConfiguredNetworks()和getScanResults()的结果进行过滤排序后得到的可用wifi列表。wifi连接—click某条AccessPoint时,执行onPreferenceTreeClick():若此AP以保存密码则使用WIfiManager的隐藏接口connect()直接连接,若之前没保存,则showDialog(WIFI_DIALOG_ID),显示自定义的com.android.settings.wifi.WifiDialog,点击对话框的按钮后onClick()被调用,根据button的id进行不同操作(忘记AP或提交、保存密码-之后刷新AP列表)。
长按某AP项时,调用onCreateContextMenu(),根据此AP是否已保存,显示 连接网络 或者 忘记、修改 网络,选中菜单调用onContextItemSelected()进行连接、忘记或修改网络操作。
让我们从自身的禁锢中放心地飞出去,重新审视自己,