我正在开发一个 Android 应用程序,它需要我扫描所有可用的公共 wifi 网络并连接到信号强度最高的网络。可以这样实现是怎么回事?
现在我的应用程序只是打开 wifi 并连接到保存的网络。
我正在开发一个 Android 应用程序,它需要我扫描所有可用的公共 wifi 网络并连接到信号强度最高的网络。可以这样实现是怎么回事?
现在我的应用程序只是打开 wifi 并连接到保存的网络。
先看一下官方帮助:
http://developer.android.com/reference/android/net/wifi/WifiManager.html
然后环顾四周,发现类似的东西:
ScanResult
level
给出可用于选择适当网络的 rssi ( ):
http://developer.android.com/reference/android/net/wifi/ScanResult.html
这是一个简单的扫描代码:
WifiManager wifi= (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifi.startScan();
// get list of the results in object format ( like an array )
List<ScanResult> results = wifi.getScanResults();`
// loop that goes through list
for (ScanResult result : results) {
Toast.makeText(this, result.SSID + " " + result.level,
Toast.LENGTH_SHORT).show();
}
请记住,您需要权限manifest.xml
:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
更新:
要通过 SSID 创建网络,我使用以下命令:
private boolean addNetworkAndActivate(ScanResult scanResult) {
WifiConfiguration wc = null;
List<WifiConfiguration> configs = wifiManager.getConfiguredNetworks();
for (WifiConfiguration wifiConfiguration : configs) {
try {
if (wifiConfiguration.SSID.equals("\"" + scanResult.SSID + "\"")) {
wc = wifiConfiguration;
break;
}
} catch (Exception e) {
}
}
// not configured, create new
if (wc == null) {
wc = new WifiConfiguration();
ConfigurationSecuritiesV8 conf = new ConfigurationSecuritiesV8();
conf.setupSecurity(wc, conf.getScanResultSecurity(scanResult), "7ej8e4jka9");
wc.SSID = "\"" + scanResult.SSID + "\"";
int res = wifiManager.addNetwork(wc);
if (res == -1)
return false;
if (!wifiManager.saveConfiguration())
return false;
}
boolean active = wifiManager.enableNetwork(wc.networkId, true);
return active;
}
课程:
public class ConfigurationSecuritiesV8 extends ConfigurationSecurities {
static final int SECURITY_NONE = 0;
static final int SECURITY_WEP = 1;
static final int SECURITY_PSK = 2;
static final int SECURITY_EAP = 3;
enum PskType {
UNKNOWN, WPA, WPA2, WPA_WPA2
}
private static final String TAG = "ConfigurationSecuritiesV14";
private static int getSecurity(WifiConfiguration config) {
if (config.allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
return SECURITY_PSK;
}
if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP) || config.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
return SECURITY_EAP;
}
return (config.wepKeys[0] != null) ? SECURITY_WEP : SECURITY_NONE;
}
private static int getSecurity(ScanResult result) {
if (result.capabilities.contains("WEP")) {
return SECURITY_WEP;
} else if (result.capabilities.contains("PSK")) {
return SECURITY_PSK;
} else if (result.capabilities.contains("EAP")) {
return SECURITY_EAP;
}
return SECURITY_NONE;
}
@Override
public String getWifiConfigurationSecurity(WifiConfiguration wifiConfig) {
return String.valueOf(getSecurity(wifiConfig));
}
@Override
public String getScanResultSecurity(ScanResult scanResult) {
return String.valueOf(getSecurity(scanResult));
}
@Override
public void setupSecurity(WifiConfiguration config, String security, String password) {
config.allowedAuthAlgorithms.clear();
config.allowedGroupCiphers.clear();
config.allowedKeyManagement.clear();
config.allowedPairwiseCiphers.clear();
config.allowedProtocols.clear();
final int sec = security == null ? SECURITY_NONE : Integer.valueOf(security);
final int passwordLen = password == null ? 0 : password.length();
switch (sec) {
case SECURITY_NONE:
config.allowedKeyManagement.set(KeyMgmt.NONE);
break;
case SECURITY_WEP:
config.allowedKeyManagement.set(KeyMgmt.NONE);
config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
if (passwordLen != 0) {
// WEP-40, WEP-104, and 256-bit WEP (WEP-232?)
if ((passwordLen == 10 || passwordLen == 26 || passwordLen == 58) && password.matches("[0-9A-Fa-f]*")) {
config.wepKeys[0] = password;
} else {
config.wepKeys[0] = '"' + password + '"';
}
}
break;
case SECURITY_PSK:
config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
if (passwordLen != 0) {
if (password.matches("[0-9A-Fa-f]{64}")) {
config.preSharedKey = password;
} else {
config.preSharedKey = '"' + password + '"';
}
}
break;
case SECURITY_EAP:
config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
// config.eap.setValue((String)
// mEapMethodSpinner.getSelectedItem());
//
// config.phase2.setValue((mPhase2Spinner.getSelectedItemPosition()
// == 0) ? "" :
// "auth=" + mPhase2Spinner.getSelectedItem());
// config.ca_cert.setValue((mEapCaCertSpinner.getSelectedItemPosition()
// == 0) ? "" :
// KEYSTORE_SPACE + Credentials.CA_CERTIFICATE +
// (String) mEapCaCertSpinner.getSelectedItem());
// config.client_cert.setValue((mEapUserCertSpinner.getSelectedItemPosition()
// == 0) ?
// "" : KEYSTORE_SPACE + Credentials.USER_CERTIFICATE +
// (String) mEapUserCertSpinner.getSelectedItem());
// config.private_key.setValue((mEapUserCertSpinner.getSelectedItemPosition()
// == 0) ?
// "" : KEYSTORE_SPACE + Credentials.USER_PRIVATE_KEY +
// (String) mEapUserCertSpinner.getSelectedItem());
// config.identity.setValue((mEapIdentityView.length() == 0) ? "" :
// mEapIdentityView.getText().toString());
// config.anonymous_identity.setValue((mEapAnonymousView.length() ==
// 0) ? "" :
// mEapAnonymousView.getText().toString());
// if (mPasswordView.length() != 0) {
// config.password.setValue(mPasswordView.getText().toString());
// }
break;
default:
LogBridge.d(TAG, "Invalid security type: " + sec);
}
// config.proxySettings = mProxySettings;
// config.ipAssignment = mIpAssignment;
// config.linkProperties = new LinkProperties(mLinkProperties);
}
private static PskType getPskType(ScanResult result) {
boolean wpa = result.capabilities.contains("WPA-PSK");
boolean wpa2 = result.capabilities.contains("WPA2-PSK");
if (wpa2 && wpa) {
return PskType.WPA_WPA2;
} else if (wpa2) {
return PskType.WPA2;
} else if (wpa) {
return PskType.WPA;
} else {
LogBridge.d(TAG, "Received abnormal flag string: " + result.capabilities);
return PskType.UNKNOWN;
}
}
@Override
public String getDisplaySecirityString(final ScanResult scanResult) {
final int security = getSecurity(scanResult);
if (security == SECURITY_PSK) {
switch (getPskType(scanResult)) {
case WPA:
return "WPA";
case WPA_WPA2:
case WPA2:
return "WPA2";
default:
return "?";
}
} else {
switch (security) {
case SECURITY_NONE:
return "OPEN";
case SECURITY_WEP:
return "WEP";
case SECURITY_EAP:
return "EAP";
}
}
return "?";
}
@Override
public boolean isOpenNetwork(String security) {
return String.valueOf(SECURITY_NONE).equals(security);
}
}
和
public abstract class ConfigurationSecurities {
/**
* @return The security of a given {@link WifiConfiguration}.
*/
public abstract String getWifiConfigurationSecurity(WifiConfiguration wifiConfig);
/**
* @return The security of a given {@link ScanResult}.
*/
public abstract String getScanResultSecurity(ScanResult scanResult);
/**
* Fill in the security fields of WifiConfiguration config.
*
* @param config
* The object to fill.
* @param security
* If is OPEN, password is ignored.
* @param password
* Password of the network if security is not OPEN.
*/
public abstract void setupSecurity(WifiConfiguration config, String security, final String password);
public abstract String getDisplaySecirityString(final ScanResult scanResult);
public abstract boolean isOpenNetwork(final String security);
public static ConfigurationSecurities newInstance() {
// if (Version.SDK < 8) {
// return new ConfigurationSecuritiesOld();
// } else {
return new ConfigurationSecuritiesV8();
// }
}
}