您的位置:首页 > 移动开发 > Android开发

Android Wifi State保存

2016-04-19 17:47 281 查看
    在Android系统中,在关开机之后发现Wifi仍然保持着关机之前的状态,就很好奇Wifi State是保存在那里的。如果是保存在Settings应用中的话,则必须要打开Settings才能触发保存的状态。但是Wifi是开机进入home界面之后就触发了。所以肯定在App层下面,framework层。
    要追查追查Wifi State,想到了每次打开关闭wifi需要调用的WifiManger.setWifiEnabled(),下面我们将一步一步追查。
    在Settings app中,在那里去触发wifi自动打开的呢,要看WiFiEnabler.java,它主要控制wifi开关控件switch。setSwitch函数是初始化WifiEnabler时调用的去打开的。onCheckedChanged函数是switch控件状态改变时,会调用的灰调函数。

public void setSwitch(Switch switch_) {
if (mSwitch == switch_) return;
mSwitch.setOnCheckedChangeListener(null);
mSwitch = switch_;
mSwitch.setOnCheckedChangeListener(this);

final int wifiState = mWifiManager.getWifiState();
boolean isEnabled = wifiState == WifiManager.WIFI_STATE_ENABLED;
boolean isDisabled = wifiState == WifiManager.WIFI_STATE_DISABLED;
mSwitch.setChecked(isEnabled);
mSwitch.setEnabled(isEnabled || isDisabled);
}

public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

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();
}
}


    可以看到setSwitch函数初始化switch时,是通过WifiManger.getWifiState()去获取的。这说明Wifi State保存在更底层。在onCheckedChanged函数中,每当wifi状态改变时,通过WiFiManager.setWifiEnabled函数去向framework设置。设置时,Wifi State也要随着更改并保存。
    接下来我们就看下WifiManager.setWifiEnabled函数。mService是IWifiManager的new出的对象。通过aidl调用到WifiService.java
public boolean setWifiEnabled(boolean enabled) {
try {
mService.setWifiEnabled(enabled);
} catch (RemoteException e) {
return false;
}
}


    我们继续看WiFiService.java,在setWifiEnabled中调用WifiStateMachine.setWifiEnabled,调用wifi状态机去loaddriver、初始化supplicant等打开wifi的操作。注意在下面有一句handleWifiToggled(enable),这个函数继续向下追有persistwifiState函数。这个函数有一句Settings.Global.putInt,这里就是保存Wifi State的地方。Settings.Global.putInt类似于Android中SharedPreference。

public synchronized boolean setWifiEnabled(boolean enable) {

if (enable) {
reportStartWorkSource();
}
mWifiStateMachine.setWifiEnabled(enable);

long ident = Binder.clearCallingIdentity();
try {
handleWifiToggled(enable);
} finally {
Binder.restoreCallingIdentity(ident);
}

return true;
}

private void handleWifiToggled(boolean wifiEnabled) {
boolean airplaneEnabled = mAirplaneModeOn.get() && isAirplaneToggleable();
if (wifiEnabled) {
if (airplaneEnabled) {
persistWifiState(WIFI_ENABLED_AIRPLANE_OVERRIDE);
} else {
persistWifiState(WIFI_ENABLED);
}
} else {
// When wifi state is disabled, we do not care
// if airplane mode is on or not. The scenario of
// wifi being disabled due to airplane mode being turned on
// is handled handleAirplaneModeToggled()
persistWifiState(WIFI_DISABLED);
}
}

private void persistWifiState(int state) {
final ContentResolver cr = mContext.getContentResolver();
mPersistWifiState.set(state);
Settings.Global.putInt(cr, Settings.Global.WIFI_ON, state);
}


    到这里我们已经知道保存Wifi State的地方了,但是开机时怎么去触发的呢。那我们继续在wifiService.java文件中找,看看什么时候去读取mPersistWiFiSate的状态的。看出有getPersistedWifiState返回Wifi State,在checkAndStartWifi中有调用。就说明Wifi State最初的状态是有checkAndStartWifi获取,并进行了Wifi状态的初始化。

private int getPersistedWifiState() {
final ContentResolver cr = mContext.getContentResolver();
try {
return Settings.Global.getInt(cr, Settings.Global.WIFI_ON);
} catch (Settings.SettingNotFoundException e) {
Settings.Global.putInt(cr, Settings.Global.WIFI_ON, WIFI_DISABLED);
return WIFI_DISABLED;
}
}

public void checkAndStartWifi() {
mAirplaneModeOn.set(isAirplaneModeOn());
mPersistWifiState.set(getPersistedWifiState());
/* Start if Wi-Fi should be enabled or the saved state indicates Wi-Fi was on */
boolean wifiEnabled = shouldWifiBeEnabled() || testAndClearWifiSavedState();
Slog.i(TAG, "WifiService starting up with Wi-Fi " +(wifiEnabled ? "enabled" : "disabled"));

// If we are already disabled (could be due to airplane mode), avoid changing persist
// state here
if (wifiEnabled) setWifiEnabled(wifiEnabled);

mWifiWatchdogStateMachine = WifiWatchdogStateMachine.makeWifiWatchdogStateMachine(mContext);
}


    为什么开机时,会调用checkAndStartWifi呢。这是因为WiFiService为system service,在开机时会被添加启动起来。我们来看SystemServer.java,调用checkAndStartWifi函数对Wifi进行初始化。
try {
Slog.i(TAG, "Connectivity Service");
connectivity = new ConnectivityService(
context, networkManagement, networkStats, networkPolicy);
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
networkStats.bindConnectivityManager(connectivity);
networkPolicy.bindConnectivityManager(connectivity);
wifi.checkAndStartWifi();
wifiP2p.connectivityServiceReady();
} catch (Throwable e) {
reportWtf("starting Connectivity Service", e);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android wifi