Sample code for Android to connect anonymous WiFi
- 2021-11-13 02:35:42
- OfStack
Preface
Because the development needs to realize wifi connection within the application, it is relatively simple to realize wifi connection combined with online data, but there is little mention of anonymous wifi connection, so share it here.
Basic use
First of all, introduce some basic concepts and tools related to the development of wifi. If you have had contact with wifi, you can skip the next section directly.
1. Permission
In Android to use system function 1, you have to apply for permission. Here, wifi needs the following permissions
<uses-permission android:name="android.permission.CHANGE_NETWORK_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.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> // System permissions required [ Location authority ]
Because wifi can be used for positioning, it is necessary to apply for positioning authority here. For devices above 6.0, positioning authority needs to be applied actively.
2.API
类名 | 功能 |
---|---|
WifiManager | wifi统1管理类,进行各种wifi操作 |
WifiInfo | 描述当前连接的wifi热点信息 |
WifiConfiguration | wifi网络配置信息 |
ScanResult | 描述扫描出的wifi热点的信息 |
The WifiManager class is the api exposed by the framework layer and is used to manage the wifi.
val mWifiManager = mContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
Through it, you can get: 1. List of configured networks. 2. The wifi of the current connection. 3. The scanned wifi. 4. And 1 constants indicate the intention of broadcasting, etc.
ScanResult class is used to store wifi scanning result information, mainly including the following contents:
属性 | 描述 |
---|---|
SSID | 描述wifi热点的名称,就是大家搜索到的直接名称,如ChinaNet |
BSSID | 姑且理解成热点的mac地址,但实际有所不同 |
networkID | 数字型的id |
level | 描述wifi信号强弱的值,值是负数,绝对值越小,信号越强 |
capabilities | 如加密方式,如WEP |
3. Monitor the change of wifi status
The change of wifi state will cause broadcast events to occur.
val filter = IntentFilter()
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION) // Eavesdropping wifi State change
filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) // Monitor and scan wifi List change
private val mReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action
if (TextUtils.isEmpty(action)) return
when (action) {
WifiManager.WIFI_STATE_CHANGED_ACTION -> {
}
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION -> {
}
}
}
}
There are enum types in the current state in WifiManager, which can be seen in the following table:
名称 | 描述 |
---|---|
WIFI_STATE_DISABLING | wifi正在关闭 |
WIFI_STATE_DISABLED | wifi关闭 |
WIFI_STATE_ENABLING | wifi正在开启 |
WIFI_STATE_ENABLED | wifi开启 |
WIFI_STATE_UNKNOWN | wifi未知 |
Connect the normal wifi
Connecting wifi can be roughly divided into the following steps:
Get the SSID that you want to connect to the WiFi hotspot, the encryption method information, and the password entered by the user Create an wifiConfigruation object based on the above information Call the method of WifiManager, pass in wifiConfigruation, and complete wifi connection
public static void connectNewWifi(Context mContext, WifiConfiguration wifiConfiguration) {
WifiManager wifiManager = (WifiManager) mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
int networkId = wifiManager.addNetwork(wifiConfiguration);
wifiManager.enableNetwork(networkId, true);
}
Therefore, the key point is how to create wifiConfigruation, and the creation process of wifi with different encryption methods is not very 1:
public WifiConfiguration createWifiConfig(String SSID, @WifiCipherType int wifiCipherType, String password) {
WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifiConfiguration.SSID = convertToQuotedString(SSID);
switch (wifiCipherType) {
case WifiCipherType.SECURITY_NONE:
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
break;
case WifiCipherType.SECURITY_WEP:
wifiConfiguration.allowedKeyManagement.set(KeyMgmt.NONE);
wifiConfiguration.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
wifiConfiguration.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
if (!TextUtils.isEmpty(password)) {
int length = password.length();
// WEP-40, WEP-104, and 256-bit WEP (WEP-232?)
if ((length == 10 || length == 26 || length == 58)
&& password.matches("[0-9A-Fa-f]*")) {
wifiConfiguration.wepKeys[0] = password;
} else {
wifiConfiguration.wepKeys[0] = '"' + password + '"';
}
}
break;
case WifiCipherType.SECURITY_PSK:
wifiConfiguration.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
if (!TextUtils.isEmpty(password)) {
if (password.matches("[0-9A-Fa-f]{64}")) {
wifiConfiguration.preSharedKey = password;
} else {
wifiConfiguration.preSharedKey = '"' + password + '"';
}
}
break;
case WifiCipherType.SECURITY_EAP:
wifiConfiguration.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
wifiConfiguration.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
wifiConfiguration.enterpriseConfig = new WifiEnterpriseConfig();
int eapMethod = 0;
int phase2Method = 0;
wifiConfiguration.enterpriseConfig.setEapMethod(eapMethod);
wifiConfiguration.enterpriseConfig.setPhase2Method(phase2Method);
if (!TextUtils.isEmpty(password)) {
wifiConfiguration.enterpriseConfig.setPassword(password);
}
break;
default:
break;
}
return wifiConfiguration;
}
At this point, the connection of wifi is completed, and then the connection results can be obtained in the broadcast. The corresponding wifi configuration information is saved in /data/misc/wifi/wpa_supplicant. conf:
network={
ssid="test"
psk="88888888"
key_mgmt=WPA-PSK
disabled=1
id_str="%7B%22creatorUid%22%3A%221000%22%2C%22configKey%22%3A%22%5C%22test%5C%22WPA_PSK%22%7D"
}
Connect anonymous wifi
Compared with ordinary wifi, anonymous wifi is different in that it does not broadcast its SSID, so it cannot be scanned directly. We need to input SSID of wifi to actively scan. First, look at the configuration information of anonymous wifi:
network={
ssid="test2"
scan_ssid=1
bssid=56:28:f8:fa:f8:a0
psk="44444444"
key_mgmt=WPA-PSK
disabled=1
id_str="%7B%22creatorUid%22%3A%221000%22%2C%22configKey%22%3A%22%5C%22test2%5C%22WPA_PSK%22%7D"
}
As you can see, there is one more scan_ssid attribute. Look at WifiConfiguration, and there is really one attribute that can be set
/**
* This is a network that does not broadcast its SSID, so an
* SSID-specific probe request must be used for scans.
*/
public boolean hiddenSSID;
So when creating WifiConfiguration, just set this attribute more:
configuration.hiddenSSID = true