Android WiFi usage record and androidwifi record
Recently, I am working on the development of WiFi for Android. The Connection Tool class refers to the tool class in this article.
Http://www.cnblogs.com/zhuqiang/p/3566686.html
Some problems encountered during development are recorded here for some solutions.
1. Identification of Wi-Fi encryption methods
String capabilities = scanResult.capabilities;
If (capabilities. contains ("WPA") | capabilities. contains ("wpa ")){
(WifiHolder) holder). setType (WifiConnector. WifiCipherType. WIFICIPHER_WPA );
} Else if (capabilities. contains ("WEP") | capabilities. contains ("wep ")){
(WifiHolder) holder). setType (WifiConnector. WifiCipherType. WIFICIPHER_WEP );
} Else {
(WifiHolder) holder). setType (WifiConnector. WifiCipherType. WIFICIPHER_NOPASS );
}
Obtain the capabilities of the scanResult to determine the Wi-Fi encryption mode.
2. Success Rate of WiFi connection
During development, I found that I failed to connect to my specified wifi when I entered the correct password. The reason is that WifiManager saves historical Wi-Fi configurations.
Public List <WifiConfiguration> cleanWifiConfiguredNetworks (String ssid ){
List <WifiConfiguration> configuredNetworks = wifiManager
. GetConfiguredNetworks ();
For (int I = 0; I <configuredNetworks. size (); I ++ ){
WifiManager. removeNetwork (configuredNetworks. get (I). networkId );
}
Return configuredNetworks;
}
It's easy to simply clear the historical configuration or set others as unavailable.
3. listener for successful wi-fi connection
I do not like broadcast listening very much. There are many problems. I will directly judge the current Wi-Fi connection information.
First, use wifiManager. getConnectionInfo () to obtain the current connection WiFi information,
ConnectionInfo. getSSID (). contains (ssid) |
ConnectionInfo. getSupplicantState ()! = SupplicantState. COMPLETED
Then, determine the wifi ssid and the wifimanager status. If both conditions are met, the WiFi connection is successful.
In this case, the project requires socket communication. In this case, a new conditional judgment is added for the latency of the obtained IP address, and an additional judgment is made for the MeteredHint parameter in wifiinfo. When this changes to true
The correct IP address is obtained. This parameter is obtained by hide. The Code is as follows:
// Call the hide method through the Reflection Method
Public boolean getWifiInfoHint (WifiInfo connectionInfo) throws InstantiationException {
Class aClass = connectionInfo. getClass ();
Try {
Method getMeteredHint = aClass. getDeclaredMethod ("getMeteredHint ");
GetMeteredHint. setAccessible (true );
Object invoke = getMeteredHint. invoke (connectionInfo );
Return (boolean) invoke;
} Catch (NoSuchMethodException e ){
E. printStackTrace ();
} Catch (IllegalAccessException e ){
E. printStackTrace ();
} Catch (InvocationTargetException e ){
E. printStackTrace ();
}
Return false;
}
How to obtain the IP address of a server:
DhcpInfo info = wifiManage. getDhcpInfo ();
String serverAddress = intToIp (info. serverAddress );
// Convert the obtained int to a real IP address. For more information, see modify the following link on the Internet.
Private String intToIp (int I ){
Return (I & 0xFF) + ". "+ (I> 8) & 0xFF) + ". "+ (I> 16) & 0xFF) + ". "+ (I> 24) & 0xFF );
}
OK. The modified code is as follows:
Package com. dopool. usersystem. hotspot;
Import android. content. Context;
Import android.net. wifi. ScanResult;
Import android.net. wifi. SupplicantState;
Import android.net. wifi. WifiConfiguration;
Import android.net. wifi. WifiConfiguration. AuthAlgorithm;
Import android.net. wifi. WifiConfiguration. KeyMgmt;
Import android.net. wifi. WifiInfo;
Import android.net. wifi. WifiManager;
Import android. OS. Handler;
Import android. OS. Message;
Import android. text. TextUtils;
Import android. util. Log;
Import com. dopool. usersystem. Constant;
Import com. zhy. http. okhttp. utils. L;
Import java. lang. reflect. Field;
Import java. lang. reflect. InvocationTargetException;
Import java. lang. reflect. Method;
Import java. util. ArrayList;
Import java. util. List;
Public class WifiConnector {
Public Handler mHandler;
WifiManager wifiManager;
/**
* Send messages to the UI
*
* @ Param info message
*/
Public void sendMsg (String info ){
If (mHandler! = Null ){
Message msg = new Message ();
Msg. obj = info;
MHandler. sendMessage (msg); // send a message to Handler
} Else {
Log. e ("wifi", info );
}
}
// WIFICIPHER_WEP is WEP, WIFICIPHER_WPA is WPA, and WIFICIPHER_NOPASS has no password
Public enum WifiCipherType {
WIFICIPHER_WEP, WIFICIPHER_WPA, WIFICIPHER_NOPASS, WIFICIPHER_INVALID
}
// Constructor
Public WifiConnector (Context context ){
// Obtain the WifiManager object
This. wifiManager = (WifiManager) context. getSystemService (Context. WIFI_SERVICE );
}
// Provides an external interface to pass in the wireless network to be connected
Public void connect (String ssid, String password, WifiCipherType ){
Thread thread = new Thread (new ConnectRunnable (ssid, password, type ));
Thread. start ();
}
// Check whether the network has been configured before
Private WifiConfiguration isExsits (String SSID ){
List <WifiConfiguration> existingConfigs = wifiManager
. GetConfiguredNetworks ();
For (WifiConfiguration existingConfig: existingConfigs ){
If (existingConfig. SSID. equals ("\" "+ SSID + "\"")){
Return existingConfig;
}
}
Return null;
}
Private WifiConfiguration createWifiInfo (String SSID, String Password,
WifiCipherType Type ){
WifiConfiguration config = new WifiConfiguration ();
Config. allowedAuthAlgorithms. clear ();
Config. allowedGroupCiphers. clear ();
Config. allowedKeyManagement. clear ();
Config. allowedPairwiseCiphers. clear ();
Config. allowedProtocols. clear ();
Config. SSID = "\" "+ SSID + "\"";
// Nopass
If (Type = WifiCipherType. WIFICIPHER_NOPASS ){
Config. allowedKeyManagement. set (KeyMgmt. NONE );
}
// Wep
If (Type = WifiCipherType. WIFICIPHER_WEP ){
If (! TextUtils. isEmpty (Password )){
If (isHexWepKey (Password )){
Config. wepKeys [0] = Password;
} Else {
Config. wepKeys [0] = "\" "+ Password + "\"";
}
}
Config. allowedAuthAlgorithms. set (AuthAlgorithm. OPEN );
Config. allowedAuthAlgorithms. set (AuthAlgorithm. SHARED );
Config. allowedKeyManagement. set (KeyMgmt. NONE );
Config. wepTxKeyIndex = 0;
}
// Wpa
If (Type = WifiCipherType. WIFICIPHER_WPA ){
Config. preSharedKey = "\" "+ Password + "\"";
Config. hiddenSSID = true;
Config. allowedAuthAlgorithms
. Set (AuthAlgorithm. OPEN );
Config. allowedGroupCiphers. set (WifiConfiguration. GroupCipher. TKIP );
Config. allowedKeyManagement. set (KeyMgmt. WPA_PSK );
Config. allowedPairwiseCiphers
. Set (WifiConfiguration. PairwiseCipher. TKIP );
// This must be modified. Otherwise, automatic reconnection is not allowed.
// Config. allowedProtocols. set (WifiConfiguration. Protocol. WPA );
Config. allowedGroupCiphers. set (WifiConfiguration. GroupCipher. CCMP );
Config. allowedPairwiseCiphers
. Set (WifiConfiguration. PairwiseCipher. CCMP );
Config. status = WifiConfiguration. Status. ENABLED;
}
Return config;
}
// Enable the wifi Function
Private boolean openWifi (){
Boolean bRet = true;
If (! WifiManager. isWifiEnabled ()){
BRet = wifiManager. setWifiEnabled (true );
}
Return bRet;
}
Private boolean closeifi (){
Boolean bRet = true;
If (wifiManager. isWifiEnabled ()){
BRet = wifiManager. setWifiEnabled (false );
}
Return bRet;
}
Class ConnectRunnable implements Runnable {
Private String ssid;
Private String password;
Private WifiCipherType;
Public ConnectRunnable (String ssid, String password, WifiCipherType type ){
This. ssid = ssid;
This. password = password;
This. type = type;
}
@ Override
Public void run (){
Try {
// Enable wifi
OpenWifi ();
SendMsg ("opened ");
Thread. sleep (200 );
// It may take some time to enable the wifi function (it usually takes about 1-3 seconds to test on the mobile phone ).
// The following statement can be executed only when the status changes to WIFI_STATE_ENABLED.
While (wifiManager. getWifiState () = WifiManager. WIFI_STATE_ENABLING ){
Try {
// To prevent the program from having a while LOOP, let it sleep for 100 ms detection ......
Thread. sleep (100 );
} Catch (InterruptedException ie ){
}
}
// Remove previous WiFi configurations
List <WifiConfiguration> saveappsenetworks = cleanWifiConfiguredNetworks (ssid );
WifiConfiguration wifiConfig = createWifiInfo (ssid, password,
Type );
If (wifiConfig = null ){
SendMsg ("wifiConfig is null! ");
Return;
}
Int netID = wifiManager. addNetwork (wifiConfig );
Boolean enabled = wifiManager. enableNetwork (netID, true );
Boolean connected = wifiManager. reconnect ();
WifiInfo connectionInfo = wifiManager. getConnectionInfo ();
Int num = 0;
Int sum = 25;
If (ssid. contains ("DoPool ")){
Sum = 35;
}
While (! ConnectionInfo. getSSID (). contains (ssid) |
ConnectionInfo. getSupplicantState ()! = SupplicantState. COMPLETED |
Ssid. contains ("DoPool ")? ! GetWifiInfoHint (connectionInfo): false ){
SendMsg (connectionInfo. getSSID () + "dd" + ssid + connectionInfo. getSupplicantState () + getWifiInfoHint (connectionInfo ));
ConnectionInfo = wifiManager. getConnectionInfo ();
Try {
Num ++;
If (num = sum ){
SendMsg (ssid + "exception ");
Return;
}
// To prevent the program from having a while LOOP, let it sleep for 100 ms detection ......
Thread. sleep (200 );
} Catch (InterruptedException ie ){
}
}
For (int I = 0; I <saveappsenetworks. size (); I ++ ){
WifiManager. addNetwork (saveappsenetworks. get (I ));
}
SendMsg (connectionInfo. toString ());
SendMsg (ssid + "connection successful! ");
} Catch (Exception e ){
// TODO: handle exception
SendMsg (ssid + "exception ");
E. printStackTrace ();
}
}
}
Private static boolean isHexWepKey (String wepKey ){
Final int len = wepKey. length ();
// WEP-40, WEP-104, and some vendors using 256-bit WEP (WEP-232 ?)
If (len! = 10 & len! = 26 & len! = 58 ){
Return false;
}
Return isHex (wepKey );
}
Private static boolean isHex (String key ){
For (int I = key. length ()-1; I> = 0; I --){
Final char c = key. charAt (I );
If (! (C> = '0' & c <= '9' | c> = 'A' & c <= 'F' | c> = 'A'
& C <= 'F ')){
Return false;
}
}
Return true;
}
Public List <WifiConfiguration> cleanWifiConfiguredNetworks (String ssid ){
List <WifiConfiguration> configuredNetworks = wifiManager
. GetConfiguredNetworks ();
For (int I = 0; I <configuredNetworks. size (); I ++ ){
WifiManager. removeNetwork (configuredNetworks. get (I). networkId );
}
Return configuredNetworks;
}
ArrayList <ScanResult> list;
Public List <ScanResult> getNoDopoolWifi (){
List <ScanResult> mSortWifi = getSortWifi ();
// Remove wifi with Dopool
For (int I = 0; I <mSortWifi. size (); I ++ ){
If (mSortWifi. get (I). SSID. contains ("DoPool ")){
MSortWifi. remove (I );
}
}
Return mSortWifi;
}
Public List <ScanResult> getSortWifi (){
WifiManager. startScan ();
List = (ArrayList <ScanResult>) wifiManager. getScanResults ();
ArrayList <ScanResult> scanResults = new ArrayList <> ();
// Remove the name of the duplicate WiFi SSID
For (int I = 0; I <list. size (); I ++ ){
If (list. get (I). SSID. equals ("") | list. get (I). frequency> 3000 ){
Continue;
}
For (int j = 0; j <= scanResults. size (); j ++ ){
If (j = scanResults. size ()){
ScanResults. add (list. get (I ));
Break;
} Else if (scanResults. get (j). SSID. equals (list. get (I). SSID )){
Break;
}
}
}
// Sort by signal strength
For (int I = 0; I <scanResults. size (); I ++ ){
For (int j = 0; j <scanResults. size (); j ++ ){
If (scanResults. get (I). level> scanResults. get (j). level ){
ScanResult temp = null;
Temp = scanResults. get (I );
ScanResults. set (I, scanResults. get (j ));
ScanResults. set (j, temp );
}
}
}
Return scanResults;
}
// Call the hide method through the Reflection Method
Public boolean getWifiInfoHint (WifiInfo connectionInfo) throws InstantiationException {
Class aClass = connectionInfo. getClass ();
Try {
Method getMeteredHint = aClass. getDeclaredMethod ("getMeteredHint ");
GetMeteredHint. setAccessible (true );
Object invoke = getMeteredHint. invoke (connectionInfo );
Return (boolean) invoke;
} Catch (NoSuchMethodException e ){
E. printStackTrace ();
} Catch (IllegalAccessException e ){
E. printStackTrace ();
} Catch (InvocationTargetException e ){
E. printStackTrace ();
}
Return false;
}
}