实现Android WIFI的扫描(特定wifi名)及连接

项目涉及到扫描特定wifi名(SSID)前缀,用户选中列表中wifi热点后,自动连接该名称的wifi。因此设计为三个工具类,一个用来扫描特定wifi名前缀的扫描工具类WifiScanner,一个根据SSID连接wifi的连接工具类WifiConnector,以及一个提供对外统一接口配置了扫描和连接信息的管理工具类WifiManager。

扫描

扫描的流程为:检测是否打开WIFI(未打开需打开)–> 注册扫描监听广播 –> 开启循环扫描线程(设置超时时间)–> 收到扫描结果广播 –> 处理结果(根据特定wifi名过滤wifi)–> 取消广播监听、扫描任务 –> 返回过滤后的结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// 摘取关键代码
public class WifiScanner {
/**
* Scan wifi with modelName
*/
public void startScan() {
turnOnWifi();
registerReceiver();
new Thread(mScanLoopRunnable).start();
}
private Runnable mScanLoopRunnable = new Runnable() {
@Override
public void run() {
mWifiMgr.startScan();
mLock.lock();
try {
mCondition.await(mScanTimeOutSec, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
mLock.unlock();
mHandler.postDelayed(this, mScanTimeOutSec * 1000);
}
};
private class WifiScanReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
List<String> ssidResults = new ArrayList<>();
List<ScanResult> scanResults = mWifiMgr.getScanResults();
int count = 0;
for (ScanResult result : scanResults) {
if (count < mMaxScanListNumber) {
if (result.SSID.startsWith(mModelName)) {
ssidResults.add(result.SSID);
count++;
}
}
}
if (ssidResults.isEmpty()) {
mScanListener.onWifiScanFailed(RemoteControlErrorDefine.NoDSCFound_Error);
} else {
mScanListener.onWifiScanSuccess(ssidResults);
}
unRegisterReceiver();
mHandler.removeCallbacks(mScanLoopRunnable);
mLock.lock();
mCondition.signalAll();
mLock.unlock();
}
}
public interface WifiScanListener {
void onWifiDisable();
void onWifiScanFailed(int errorType);
void onWifiScanSuccess(List<String> results);
}
}

连接

连接的流程为:开启连接线程 –> 注册客户端wifi状态改变广播 –> 根据ssid、密码、安全模式连接wifi –> 返回wifi连接结果 –> 取消广播监听

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// 摘取关键代码
public class WifiConnector {
/**
* connect to wifi
*/
public void connect(final String ssid, final String password, final int mode) {
new Thread(new Runnable() {
@Override
public void run() {
registerReceiver();
if (!connectWifi(ssid, password, mode)) {
mWifiConnectListener.onWifiConnectCompleted(false);
} else {
mWifiConnectListener.onWifiConnectCompleted(true);
}
unRegisterReceiver();
}
}).start();
}
private boolean connectWifi(String ssid, String password, int mode) {
WifiConfiguration cfg = new WifiConfiguration();
cfg.SSID = "\"" + ssid + "\"";
switch (mode) {
case WEP_SECURITY_MODE:
cfg.wepKeys[0] = "\"" + password + "\"";
cfg.wepTxKeyIndex = 0;
cfg.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
cfg.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
break;
case WPA_SECURITY_MODE:
cfg.preSharedKey = "\"" + password + "\"";
break;
case OPEN_SECURITY_MODE:
cfg.wepKeys[0] = "\"" + password + "\"";
cfg.wepTxKeyIndex = 0;
cfg.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
break;
default:
cfg.preSharedKey = "\"" + password + "\"";
}
cfg.status = WifiConfiguration.Status.ENABLED;
mNetworkID = mWifiMgr.addNetwork(cfg);
mLock.lock();
mIsConnnected = false;
if (!mWifiMgr.enableNetwork(mNetworkID, true)) {
mLock.unlock();
return false;
}
try {
mCondition.await(WIFI_CONNECT_TIMEOUT_SEC, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
mLock.unlock();
return mIsConnnected;
}
private class WiFiConncetReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (!WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(intent.getAction())) {
return;
}
mLock.lock();
WifiInfo info = mWifiMgr.getConnectionInfo();
if (info.getNetworkId() == mNetworkID && info.getSupplicantState() == SupplicantState.COMPLETED) {
mIsConnnected = true;
mCondition.signalAll();
}
mLock.unlock();
}
}
public interface WifiConnectListener {
void onWifiConnectCompleted(boolean isConnected);
}
}

管理

1
2
3
4
5
6
7
8
9
10
11
12
public class WifiController implements WifiScanner.WifiScanListener, WifiConnector.WifiConnectListener {
// init scanner and connector
public WifiController(Context context) {
mContext = context;
mWifiMgr = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
mScanner = new WifiScanner(context, mWifiMgr);
mScanner.setmModelName("XXX");
mScanner.setScanListener(this);
mConnector = new WifiConnector(context, mWifiMgr);
mConnector.setConnectListener(this);
}
}

权限

在Manifest.xml中配置相应权限

1
2
3
4
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />