由对Androidsetting的源码分析之WiFi模块的界面fragment为WiFisettings.java,关于setting模块的源码分析可以参考
public class WifiSettings extends RestrictedSettingsFragment
implements DialogInterface.OnClickListener
View view = inflater.inflate(R.layout.setup_preference, container, false);
View v = inflater.inflate(R.layout.add_preference_list_fragment,null);
mP2pSupported = getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT);
public boolean hasSystemFeature(String name) {
return systemFeatureList.containsKey(name) ? systemFeatureList.get(name) : false;
}
mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
if (getResources().getBoolean(R.bool.set_wifi_priority)) {
addPreferencesFromResource(R.xml.wifi_sort_settings);
mDefaultTrustAP
= (PreferenceCategory)findPreference("default_trust_access_points");
mConfigedAP = (PreferenceCategory)findPreference("configed_access_points");
mUnKnownAP = (PreferenceCategory)findPreference("unknown_access_points");
}
else {
addPreferencesFromResource(R.xml.wifi_settings);
}
对于boolean值“set_wifi_priority”的值可以查看Z:\L7-A1\android\packages\apps\Settings\res\values\bools.xml文件
该值表示whether to show hotspot via the ap's classification接入点优先级设定即是否按照所搜索到的WiFi优先级来显示Wifi列表,可以看到等级有三种:默认的信任接入点,信任接入点,未知接入点
因为在这里boolean值被设置为false,所以不按优先级排序5>,接下来就是添加WiFi开关,至于通过代码在导航栏actionbar添加switch的代码类似蓝牙,在此不再赘述,可以看到,蓝牙开关switch传入了WifiEnabler,所以对于Wifi的开关的管理位于WiFiEnablerswitch中
mWifiEnabler = new WifiEnabler(activity, actionBarSwitch);
//当WiFi状态发生改变时会发送该广播
mIntentFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
// The order matters! We really should not depend on this. :(
mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
//当设备网络状态发生改变时会发送该广播
mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
/**
* Broadcast intent action indicating that the state of establishing a connection to
* an access point has changed.One extra provides the new
* {@link SupplicantState}. Note that the supplicant state is Wi-Fi specific, and
* is not generally the most useful thing to look at if you are just interested in
* the overall state of connectivity.
* @see #EXTRA_NEW_STATE
* @see #EXTRA_SUPPLICANT_ERROR
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String SUPPLICANT_STATE_CHANGED_ACTION =
"android.net.wifi.supplicant.STATE_CHANGE";
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
//WiFi状态生改变时去更新switch的状态,WiFi的状态存在于WifiManager.EXTRA_WIFI_STATE
handleWifiStateChanged(intent.getIntExtra(
WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN));
//needPrompt方法用于判断是否是飞行模式以及飞行模式是否无效
if (WifiSettings.needPrompt(context)) {
setSwitchChecked(false);
}
} else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) {
//连接发生改变时的更新,WifiManager.EXTRA_NEW_STATE存放改变后的状态
if (!mConnected.get()) {
handleStateChanged(WifiInfo.getDetailedStateOf((SupplicantState)
intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE)));
}
} else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
//网络状态发生改变时的更新
NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(
WifiManager.EXTRA_NETWORK_INFO);
mConnected.set(info.isConnected());
handleStateChanged(info.getDetailedState());
}
}
};
private void handleWifiStateChanged(int state) {
switch (state) {
case WifiManager.WIFI_STATE_ENABLING://正在打开WiFi
mSwitch.setEnabled(false);
break;
case WifiManager.WIFI_STATE_ENABLED://WiFi已经打开
setSwitchChecked(true);
mSwitch.setEnabled(true);
break;
case WifiManager.WIFI_STATE_DISABLING://正在关闭WiFi
mSwitch.setEnabled(false);
break;
case WifiManager.WIFI_STATE_DISABLED://WiFi已经关闭
setSwitchChecked(false);
mSwitch.setEnabled(true);
break;
default:
setSwitchChecked(false);
mSwitch.setEnabled(true);
break;
}
}
private void handleStateChanged(@SuppressWarnings("unused") NetworkInfo.DetailedState state) {
// After the refactoring from a CheckBoxPreference to a Switch, this method is useless since
// there is nowhere to display a summary.
// This code is kept in case a future change re-introduces an associated text.
/*
// WifiInfo is valid if and only if Wi-Fi is enabled.
// Here we use the state of the switch as an optimization.
if (state != null && mSwitch.isChecked()) {
WifiInfo info = mWifiManager.getConnectionInfo();
if (info != null) {
//setSummary(Summary.get(mContext, info.getSSID(), state));
}
}
*/
}
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//Do nothing if called as a result of a state machine event
if (mStateMachineEvent) {
return;
}
if (mContext.getResources().getBoolean(R.bool.wifi_to_cell)) {
ConnectivityManager mConnService = (ConnectivityManager) mContext.
getSystemService(Context.CONNECTIVITY_SERVICE);
if (mConnService != null) {
NetworkInfo netInfo = (NetworkInfo) mConnService
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (netInfo != null && netInfo.isConnected()) {
Settings.System.putInt(mContext.getContentResolver(), WIFI_IS_CONNECTED,
CONNECTED);
} else {
Settings.System.putInt(mContext.getContentResolver(), WIFI_IS_CONNECTED,
DISCONNECTED);
}
}
}
// Show toast message if Wi-Fi is not allowed in airplane mode
//判断是否在飞行模式中WiFi是不允许的
if (isChecked
&& (WifiSettings.needPrompt(mContext) || !WirelessSettings.isRadioAllowed(
mContext, Settings.Global.RADIO_WIFI))) {
Toast.makeText(mContext, R.string.wifi_in_airplane_mode,
Toast.LENGTH_SHORT).show();
// Reset switch to off. No infinite check/listenenr loop.
buttonView.setChecked(false);
return;
}
// Disable tethering if enabling Wifi
int wifiApState = mWifiManager.getWifiApState();
if (isChecked && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
(wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
mWifiManager.setWifiApEnabled(null, false);
}
// shouldn't setWifiEnabled(true) in airplane mode.
if (isChecked && WifiSettings.needPrompt(mContext)) {
return;
} else {
//setWifiEnabled打开或者关闭WiFi的方法,会发送WiFi状态改变的广播:WIFI_STATE_CHANGED_ACTION
if (mWifiManager.setWifiEnabled(isChecked)) {
// Intent has been taken into account, disable until new state
// is active
mSwitch.setEnabled(false);
} else {
// Error
Toast.makeText(mContext, R.string.wifi_error,
Toast.LENGTH_SHORT).show();
}
}
}
对于mStateMachineEvent的值是在对switch进行设置时赋值,起开关保护的作用,保证当点击switch的时候先将switch状态设置成功再进入点击事件方法
private void setSwitchChecked(boolean checked) {
if (checked != mSwitch.isChecked()) {
mStateMachineEvent = true;
mSwitch.setChecked(checked);
mStateMachineEvent = false;
}
}