最近做WiFi方面需求,遇到一个问题就是连接扫描的的热点总是连接不上(不经加密的),代码如下:
/*连接到热点*/
public void connectToHotpot(){
List<ScanResult> results = mWifiManager.getScanResults();
for (ScanResult result : results){
if (result.SSID.contains("zeus")){
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.SSID = result.SSID;
int wcgID = mWifiManager.addNetwork(wifiConfig);
mWifiManager.enableNetwork(wcgID, true);
break;
}
}
}
先获取一下附近WiFi列表,如果是需要连接的WiFi,就去连接,但是执行了
mWifiManager.enableNetwork(wcgID, true);这句话以后并没有连接上,(手动连接一次以后就可以自动连接了),后来在帖子上看到了答案,正确代码如下:
/*连接到热点*/
public void connectToHotpot(){
List<ScanResult> results = mWifiManager.getScanResults();
for (ScanResult result : results){
if (result.SSID.contains("zeus")){
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.SSID = result.SSID;
wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wifiConfig.wepTxKeyIndex = 0;
int wcgID = mWifiManager.addNetwork(wifiConfig);
mWifiManager.enableNetwork(wcgID, true);
break;
}
}
}
因为当时创建热点是不加密的,也就是开放的,这里enableNetwork的时候也需要去明确一下加密方式为none,源码中WiFi的加密方式有以下几种:
/** WPA is not used; plaintext or static WEP could be used. */
public static final int NONE = 0;
/** WPA pre-shared key (requires {@code preSharedKey} to be specified). */
public static final int WPA_PSK = 1;
/** WPA using EAP authentication. Generally used with an external authentication server. */
public static final int WPA_EAP = 2;
/** IEEE 802.1X using EAP authentication and (optionally) dynamically
* generated WEP keys. */
public static final int IEEE8021X = 3;
/** WPA2 pre-shared key for use with soft access point
* (requires {@code preSharedKey} to be specified).
* @hide
*/
public static final int WPA2_PSK = 4;
下面是创建热点的代码:
/** set WiFi hot spot is enableed */
private boolean setWifiApEnabled(WifiConfiguration configuration, boolean enabled)
{
try
{
if (enabled)
{
mWifiManager.setWifiEnabled(false);
}
Method method = mWifiManager.getClass().getMethod("setWifiApEnabled",
WifiConfiguration.class, boolean.class);
return (Boolean) method.invoke(mWifiManager, configuration, enabled);
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
开启热点是需要反射的,因为setWifiApEnable方法在源码中是@hide的,目前并不对外开放:
/**
* Start AccessPoint mode with the specified
* configuration. If the radio is already running in
* AP mode, update the new configuration
* Note that starting in access point mode disables station
* mode operation
* @param wifiConfig SSID, security and channel details as
* part of WifiConfiguration
* @return {@code true} if the operation succeeds, {@code false} otherwise
*
* @hide Dont open up yet
*/
public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
try {
mService.setWifiApEnabled(wifiConfig, enabled);
return true;
} catch (RemoteException e) {
return false;
}
}
但是,好像是有个例外,htc的手机开启热点需要特殊处理一下:
/** enable and disable htc WiFi hotspot, 2013-12-31 add special for htc */
private boolean enableHtcHotspot(WifiConfiguration apConfig, boolean enable)
{
Method method = null;
try
{
method = mWifiManager.getClass().getMethod("setWifiApEnabled",
WifiConfiguration.class, Boolean.TYPE);
}
catch (NoSuchMethodException e)
{
e.printStackTrace();
}
// 返回热点打开状态
boolean flag = false;
try
{
flag = (Boolean) method.invoke(mWifiManager, apConfig, enable);
}
catch (IllegalArgumentException e)
{
flag = false;
e.printStackTrace();
}
catch (IllegalAccessException e)
{
flag = false;
e.printStackTrace();
}
catch (InvocationTargetException e)
{
flag = false;
e.printStackTrace();
}
return flag;
}
因为也是初次接触WiFi方面,所以遇到的问题比较多,需要注意的点:
1、加密方式,连接的时候一定要明确创建热点时使用的加密方式。
2、注意热点和WiFi是不能同时开的。
以上是自己遇到的坑,记录一下,关于WiFi这块周末研究一下。