我需要扫描未知SSID列表并使用一些预定义密码登录该访问点。如果成功,则继续下一个任务。如果失败,则尝试登录下一个SSID。
我尝试尽可能多地注册以查看哪个工作正常:
receiverWifi = new WifiReceiver();
registerReceiver(receiverWifi, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
registerReceiver(receiverWifi, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
registerReceiver(receiverWifi, new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION));
registerReceiver(receiverWifi, new IntentFilter(WifiManager.NETWORK_IDS_CHANGED_ACTION));
registerReceiver(receiverWifi, new IntentFilter(WifiManager.ACTION_PICK_WIFI_NETWORK));
registerReceiver(receiverWifi, new IntentFilter(WifiManager.ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE));
registerReceiver(receiverWifi, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
registerReceiver(receiverWifi, new IntentFilter(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION));
我用这样的密码连接ssid:
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.SSID = String.format("\"%s\"", ssid);
wifiConfig.preSharedKey = String.format("\"%s\"", password);
netId = mainWifi.addNetwork(wifiConfig);
if (netId != -1) {
if (mainWifi.disconnect())
if (mainWifi.enableNetwork(netId, true))
if (mainWifi.reconnect()) {
}
}
它确实流向了连接:
class WifiReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
} else if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI &&
networkInfo.isConnected()) {
WifiInfo wifiInfo = mainWifi.getConnectionInfo();
ssid = wifiInfo.getSSID();
//able to know Wifi connected to ssid here
}
} else if (intent.getAction().equalsIgnoreCase(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
}
}
}
但是我怎么知道这个SSID密码是否失败?我想知道密码是否失败,然后代码将尝试下一个SSID。但是,我应该使用哪个操作来了解密码尝试失败?目前我注意到只有android.net.wifi.STATE_CHANGE
动作继续接收,但它并不意味着密码失败。
答案 0 :(得分:2)
WifiManager.ERROR_AUTHENTICATING
并不总是出现,所以我最终得到了这个:
class WifiReceiverResult extends BroadcastReceiver {
boolean assoc = false;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
SupplicantState supl_state = ((SupplicantState)intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE));
switch (supl_state) {
case ASSOCIATED:
assoc = true;
break;
case FOUR_WAY_HANDSHAKE: //need this because ASSOCIATED sometimes skipped
assoc = true;
break;
case DISCONNECTED:
if (assoc) {
assoc = false;
//... try next SSID
}
break;
...
由于DISCONNECTED
仅在ASSOCIATED
或FOUR_WAY_HANDSHAKE
出现一次时才有效,因此我将assoc
变量设为安全防范。反映“无效密码”当然不是100%准确,但我没有其他更好的选择。
[更新] 请记住,以上不是最终代码,您还应该处理超时和DISCONNECTED的最大尝试次数,否则它可能只在几分钟后成功(这在我的要求中是不可接受的) ,我最好尝试下一个SSID,然后再次重试整个SSID列表)或重复SCANNING ......无限制地断开连接。
这就是我的所作所为:
Handler myHandler = new Handler(Looper.getMainLooper());
Runnable runner = new Runnable() {
@Override
public void run() {
if (isTimeout) {
//Network idle timeout 15 seconds, do scanning next again
List<WifiConfiguration> list = mainWifi.getConfiguredNetworks(); //here might hang for 20 seconds !
for( WifiConfiguration i : list ) {
mainWifi.removeNetwork(i.networkId);
mainWifi.saveConfiguration();
}
connectAPWithTimeout();
}
}
};
...
void connectAPWithTimeout() {
if (runner != null) {
myHandler.removeCallbacks(runner);
}
myHandler.postDelayed(runner, 15000);
isTimeout = true;
try {
receiverWifiR.connectToAP(); //my custom method to connect to next ssid hotspot
} catch (NullPointerException e) {
}
}
...
class WifiReceiverResult extends BroadcastReceiver {
int attempt = 0;
...
@Override
public void onReceive(Context context, Intent intent) {
...
case DISCONNECTED:
attempt+=1;
if (assoc || attempt > 2) {
isTimeout = false;
assoc = false;
attempt = 0;
connectAPWithTimeout();
}
break;
不要忘记在退出课程时重新删除回调或连接之前删除回调:
isTimeout = false;
if (runner != null) {
myHandler.removeCallbacks(runner);
}
答案 1 :(得分:1)
添加BrocastReciver以执行操作“SUPPLICANT_STATE_CHANGED_ACTION” 然后在onRecive
中添加波纹管代码if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
int linkWifiResult = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, 123);
if (linkWifiResult == WifiManager.ERROR_AUTHENTICATING) {
Log.i(TAG,"pwd error);
}
}