https://github.com/zytc2009/BigTeam_learning
分类: Android平台
2013-01-15 19:59:30
快牙是一款基于WIFi热点的快速传文件的程序(基于Android版本)。首先是通过把其中的一个手机设置成Wifi hotspot,别的手机通过wifi查找wifi hotspot来确认。
1、 搜索过滤
这个通过快牙运行前设置用户名,搜索过滤时,快牙只找出用快牙启动的热点。别的WIfi热点都找不出来。想反编译快牙,NND的,还混淆了。
打开Wifi热点,快牙把WIFI 的 SSID已经修改了,通过把用户名sha一下,得出字串。搜索出来的再返向一下,前面再加上关键字如D511,就是用户名,这样就可以过滤。思路基本上是这样的。
2、 WIfi热点的打开
这个主要是通过WifiManager中的Hide的API来实现。在google搜索也有讲到的,主要就是用到setWifiApEnabled这个Hide的函数。
我们就可以通过反射的方法。我把这个写成了一个class.
public static class WifiApManager {
public static final int WIFI_AP_STATE_FAILED= 4;
private final WifiManager mWifiManager;
public WifiApManager(Context context) {
mWifiManager = (WifiManager) context
.getSystemService(Context.WIFI_SERVICE);
}
public booleansetWifiApEnabled(WifiConfiguration config,
boolean enabled) {
try {
if (enabled) { // disable WiFi in any case
mWifiManager.setWifiEnabled(false);
}
Method method = mWifiManager.getClass().getMethod(
"setWifiApEnabled", WifiConfiguration.class,
boolean.class);
return (Boolean) method.invoke(mWifiManager, config, enabled);
} catch(Exception e) {
e.printStackTrace();
return false;
}
}
public int getWifiApState() {
try {
Method method = mWifiManager.getClass().getMethod(
"getWifiApState");
return (Integer) method.invoke(mWifiManager);
} catch(Exception e) {
e.printStackTrace();
return WIFI_AP_STATE_FAILED;
}
}
public WifiConfiguration getWifiApConfiguration() {
try {
Method method = mWifiManager.getClass().getMethod(
"getWifiApConfiguration");
return (WifiConfiguration) method.invoke(mWifiManager);
} catch(Exception e) {
e.printStackTrace();
return null;
}
}
public booleansetWifiApConfiguration(WifiConfiguration config) {
try {
Method method = mWifiManager.getClass().getMethod(
"setWifiApConfiguration",WifiConfiguration.class);
return (Boolean) method.invoke(mWifiManager, config);
} catch(Exception e) {
e.printStackTrace();
return false;
}
}
public intsetWifiApConfig(WifiConfiguration config) {
try {
Method method = mWifiManager.getClass().getMethod(
"setWifiApConfig",WifiConfiguration.class);
return (Integer) method.invoke(mWifiManager, config);
} catch(Exception e) {
e.printStackTrace();
return WIFI_AP_STATE_FAILED;
}
}
}
这个函数与方法就可以在android 的源代码中打开WifiManager.java中找到,通过设置wificonfiguration就可以了。网上也有些sample,基本原理都是这样实现的。还可以listen这个hotspot的消息,实现一些功能。
但这些方法都只能在非HTC的phone中实现,在htc 的phone中,只能启动hotspot,但不能修改SSID等参数。但WLAN 热点设置是可以修改这些参数的。
3、 解决方法
HTC喜欢自己增加个api什么的是常有事,我就把HTC 手机wifimanager下的所有函数都反射出来看一下,试一下。于是
Method[] classMethods = null;
try {
classMethods = wifi.getClass().getDeclaredMethods();
} catch(SecurityException e) {
Log.w(TAG, "getDeclaredMethods failed");
}
for (int i = 0;i < classMethods.length; i++)
{
Log.i(TAG, "found api: "+ classMethods[i].getName());
if(classMethods[i].getName().equalsIgnoreCase("setWifiApConfig")){
Type[] typeParam = classMethods[i].getGenericParameterTypes();
for(Type t:typeParam){
Log.w(TAG, "getGenericParameterTypes:" +t.toString());
}
}
}
found api: NotifyWifiPhoneCallComeIn
found api: NotifyWifiPhoneCallEnd
found api: acquirePowerActiveReq
found api: addNetwork
found api: addToBlacklist
found api: asyncConnect
found api: cancelWps
found api: clearBlacklist
found api: connectNetwork
found api: connectNetwork
found api: createMulticastLock
found api: createWifiLock
found api: createWifiLock
found api: disableNetwork
found api: disableSsdpPacket
found api: disconnect
found api: enableAutoIP
found api: enableNetwork
found api: enablePowerActiveForFotaDownload
found api: enablePowerActiveMode
found api: enableSsdpPacket
found api: forgetNetwork
found api: getAssocListStr
found api: getClientInfo
found api: getConfigFile
found api: getConfiguredNetworks
found api: getConnectionInfo
found api: getConnectionPolicyEnabled
found api: getDhcpInfo
found api: getDockWifiApAutoEnabled
found api: getDockWifiAutoEnabled
found api: getFrequencyBand
found api: getHotspotNumAllowedChannels
found api: getMessenger
found api: getMostPreferredNetwork
found api: getRequestedList
found api: getScanResults
found api: getSmartWifiState
found api: getWagAddress
found api: getWagAsUserDefined
found api: getWifiApConfiguration
found api: getWifiApState
found api: getWifiOffloadEnabled
found api: getWifiState
found api: initializeMulticastFiltering
found api: isDualBandSupported
found api: isMulticastEnabled
found api: isWifiApEnabled
found api: isWifiEnabled
found api: isWifiPowerModeNormal
found api: isWlanMacValid
found api: pingSupplicant
found api: reassociate
found api: reconnect
found api: releasePowerActiveReq
found api: removeNetwork
found api: resetDhcpConfig
found api: saveConfiguration
found api: saveNetwork
found api: setConnectionPolicyEnabled
found api: setCountryCode
found api: setDockWifiApAutoEnabled
found api: setDockWifiAutoEnabled
found api: setFrequencyBand
found api: setHotspotAutoChannel
found api: setMostPreferredNetwork
found api: setWagAddress
found api: setWagAsUserDefined
found api: setWifiApConfig
getGenericParameterTypes:class android.net.wifi.WifiConfiguration
found api: setWifiApConfiguration
found api: setWifiApEnabled
found api: setWifiApMacList
found api: setWifiEnabled
found api: setWifiEnabledPersist
found api: setWifiOffloadEnabled
found api: setWifiPowerSavingMode
found api: setWpsPbcMode
found api: setWpsPinMode
found api: setWpsRegMode
found api: startScan
found api: startScanActive
found api: startWifi
found api: startWps
found api: stopWifi
found api: stopWps
found api: updateNetwork
found api: access$000
found api: access$008
found api: access$010
found api: addOrUpdateNetwork
found api: calculateSignalLevel
found api: calculateSignalLevel
found api: compareSignalLevel
从API的名字来看,只有setWifiApConfig这个,是不是在调用之前,或之后要用HTC专利的API呢?参数得到也是WifiConfiguration,用代码试试看,失败。跟我猜想的不一样。继续试别的api都不行。
继续在网上搜,基本上都是问的,没有答案。而且快牙能做,我肯定能做。
是不是wificonfiguration中有变化呢?对于google源码中的wificonfiguration.java中已看过了。已经调试时看
有一个mWifiApProfile,类型是HotspotProfile,搜一下,全是微软的,类型也不正确,还是自己再研究吧
设置成mWifiApProfile会不会行呢,试试看
mnetConfig = new Wificonfiguration();
….
Field localField1;
try {
localField1 = WifiConfiguration.class.getDeclaredField("mWifiApProfile");
localField1.setAccessible(true);
Object localObject2 = localField1.get(mnetConfig);
localField1.setAccessible(false);
if(localObject2!=null){
Field localField5 = localObject2.getClass().getDeclaredField("SSID");
localField5.setAccessible(true);
localField5.set(localObject2, netConfig.SSID);
localField5.setAccessible(false);
Field localField4 = localObject2.getClass().getDeclaredField("BSSID");
localField4.setAccessible(true);
localField4.set(localObject2, netConfig.BSSID);
localField4.setAccessible(false);
Field localField6 = localObject2.getClass().getDeclaredField("dhcpEnable");
localField6.setAccessible(true);
localField6.setInt(localObject2, 1);
localField6.setAccessible(false);
}
} catch(Exception e) {
e.printStackTrace();
}
再去调用setWifiApEnabled,现在就可以成功了。
这样我们就可以通过SSID来过滤特定的WIfi热点,这样不是我们程序启动的,就不要处理,提高软件smart性,还是很有好处的。