SoftAP 打开时调用的相关函数解析
Softap字面意思是用软件实现AP的功能,让你的移动设备可以作为一个路由,让别的站点链接。比如让别人的手机连上你的已经打开AP功能的手机,玩联机游戏或者上网等等
但事实上此功能是需要硬件以及驱动的支持才能真正的实现的。
Softap打开流程。
在Android系统的Setting界面的wireless配置项中会看到一个“Portable Wi-Fi hotspot” 跟一个"Configure Wi-Fi hotspot setting"选项,可以进入系统配置AP的名称,加密方式,密码等。 如下图
当你做完这些设置,系统接受的AP设置界面变化打开的响应,从此开启了整个Android SoftAP的序幕。
首先./packages/apps/Settings/src/com/android/settings/TetherSettings.java 的onPreferenceChange 函数接收到Softap状态改变信息
public boolean onPreferenceChange(Preference preference, Object value) {
boolean enable = (Boolean) value;
if (enable) {
startProvisioningIfNecessary(WIFI_TETHERING);
} else {
mWifiApEnabler.setSoftapEnabled(false);
}
return false;
}
Softap开启时,enable 为真,因而执行startProvisioningIfNecessary(WIFI_TETHERING);
private void startProvisioningIfNecessary(int choice) {
mTetherChoice = choice;
if (isProvisioningNeeded()) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setClassName(mProvisionApp[0], mProvisionApp[1]);
startActivityForResult(intent, PROVISION_REQUEST);
} else {
startTethering();
}
}
isProvisioningNeeded 用来检测是否需要进行一些准备工作
如果无需准备工作则执行startTethering 大戏即将上演了 期待ing
private void startTethering() {
switch (mTetherChoice) {
case WIFI_TETHERING:
mWifiApEnabler.setSoftapEnabled(true);
break;
case BLUETOOTH_TETHERING:
// turn on Bluetooth first
break;
case USB_TETHERING:
setUsbTethering(true);
break;
default:
//should not happen
break;
}
}
这里 mTetherChoice == WIFI_TETHERING 所以继而执行WiFiApEnable.java中的setSoftapEnabled(true)函数
也从此处也跳出了Setting的代码 跳入了Android WIFI 子系统的framework层
./packages/apps/Settings/src/com/android/settings/wifi/WifiApEnabler.java
public void setSoftapEnabled(boolean enable) {
final ContentResolver cr = mContext.getContentResolver();
/**
* Disable Wifi if enabling tethering
*/
int wifiState = mWifiManager.getWifiState(); //获取当前wifi的状态 如果开启则关闭且保存状态信息到变量中
if (enable && ((wifiState == WifiManager.WIFI_STATE_ENABLING) ||
(wifiState == WifiManager.WIFI_STATE_ENABLED))) {
mWifiManager.setWifiEnabled(false);
Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 1);
}
if (mWifiManager.setWifiApEnabled(null, enable)) {
/* Disable here, enabled on receiving success broadcast */
mCheckBox.setEnabled(false);
} else {