0

我有一個要求,掃描未知的SSID列表,並使用一些預定義的密碼登錄該訪問點。如果成功,那麼繼續下一個任務。如果失敗,則嘗試登錄下一個SSID。Android - 如何知道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行動繼續接收,但它並不意味着密碼失敗。

回答

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); 
    } 
} 
+2

謝謝,但我注意到'WifiManager。 ERROR_AUTHENTICATING'並不總是有效。 –

+0

不適用於我。 – AJit

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纔有效如果ASSOCIATEDFOUR_WAY_HANDSHAKE出現一次,那麼我將一個assoc變量作爲安全警戒。反映「無效密碼」當然不是100%準確的,但我沒有其他更好的選擇。

[更新]記住,上面是不是最終的代碼,你也應該處理DISCONNECTED的超時和最大的努力,否則可能幾分鐘後才成功(這是在我的要求是不可接受的,我最好嘗試下一個SSID,然後再次重試整個SSID列表),或者無限重複SCANNING ... DISCONNECTECT階段。

這是我做的:

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); 
}