SoftAp界面开启流程(让你的手机支持SoftAp功能)
市面上大多数手机支持SoftAp功能,有少数手机没有打开SoftAp的界面设置,所以无法开启此功能(当然有些山寨手机平板打开了此设置功能也不一定能使用SoftAP,因为此功能需要WIFI芯片与WIFI驱动的支持才能真正意义上实现)。
深入代码介绍一下手机 Portable Wi-Fi hostpot 界面开启条件
上文《Android SoftAp支持 (一)》提到当勾选Portable Wi-Fi hostpot,系统的Setting程序TetherSettings.java将响应此动作。tether这个词意思是拴绳,拴住的意思,理解起来有点晦涩,这里我的理解是分享的意思,比如 WIFI_TETHERING(用WIFI分享网路), USB_TETHERING(用USB分享网络)……
那么这些网络分享如何满足什么条件才开启呢?
从WirelessSettings开始说
在packages/apps/Settings/src/com/android/settings/WirelessSettings.java 的onCreate方法中会去检测系统是否Tether
[cpp] view plain copy print ?
"font-size:14px;">// Disable Tethering if it's not allowed or if it's a wifi-only device
ConnectivityManager cm =
(ConnectivityManager) activity.getSystemService(Context.CONNECTIVITY_SERVICE);
if(isSecondaryUser || !cm.isTetheringSupported()) {
getPreferenceScreen().removePreference(findPreference(KEY_TETHER_SETTINGS));
} else{
Preference p = findPreference(KEY_TETHER_SETTINGS);
p.setTitle(Utils.getTetheringLabel(cm));
}
protectByRestrictions(KEY_TETHER_SETTINGS);
1)调用获取ConnectivityManager实例对象,并调用isTetheringSupported方法来检测是否支持Tether
2)调用getTetheringLabel查看支持哪些网络共享方式,并显示到界面
先看isTetheringSupported方法
[cpp] view plain copy print ?
"font-size:14px;">publicboolean isTetheringSupported() {
try{
returnmService.isTetheringSupported();
} catch(RemoteException e) {
returnfalse;
...
它调用了frameworks/base/services/java/com/android/server/ConnectivityService.java 的isTetheringSupported 方法
[cpp] view plain copy print ?
"font-size:14px;">publicboolean isTetheringSupported() {
enforceTetherAccessPermission();
intdefaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
boolean tetherEnabledInSettings = (Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.TETHER_SUPPORTED, defaultVal) != 0);
returntetherEnabledInSettings && ((mTethering.getTetherableUsbRegexs().length != 0 ||
mTethering.getTetherableWifiRegexs().length != 0 ||
mTethering.getTetherableBluetoothRegexs().length != 0) &&
mTethering.getUpstreamIfaceTypes().length != 0);
} 读取系统ro.tether.denied的属性,返回true则表示关闭tether功能,返回false表示打开tether功能。(有些设备不能显示portable wifi 就是因为此属性返回true,这里需要修改设置为false)
之后会检测是否有配置文件配置了tether,有则使用设置的值,没有查询到配置这使用查询ro.tether.denied属性的默认值。
这里我们假设得到的tetherEnableInSettings为ture,也不意味着就能正确打开Portable Wi-Fi hostpot 界面。因为还需要检测是否支持WIFI网络共享配置
mTethering.getTetherableWifiRegexs().length!=0 检测是否支持网络共享配置,这里Android4.4 与之前的版本有一定区别,但总体不变,大家可以参考其他代码做一些变通
getTetherableWifiRegexs()方法
frameworks/base/services/java/com/android/server/connectivity/Tethering.java
[cpp] view plain copy print ?
returnmTetherableWifiRegexs; 直接返回了一个变量。 此变量在frameworks/base/services/java/com/android/server/connectivity/Tethering.java
updateConfiguration()方法中赋值
[cpp] view plain copy print ?
mTetherableWifiRegexs = tetherableWifiRegexs; 而 tetherableWifiRegexs变量赋值也在此方法中
[cpp] view plain copy print ?
String[] tetherableWifiRegexs = mContext.getResources().getStringArray(
com.android.internal.R.array.config_tether_wifi_regexs);
这里的config_tether_wifi_regexs数组由配置文件生成
配置文件config.xml
frameworks/base/core/res/res/values/config.xml
[html] view plain copy print ?