androidandroid-wifiandroid-wireless

How to connect to a wireless network in android?


I have managed to scan for wireless networks and obtain scan results in my application. but is there a way i could possibly connect to them using my app itself? I was wondering whether I would have to specify the encryption type for the network i'm trying to connect? and my requirement would be to connect to any wireless network irrespective of it's encryption type?

Any ideas? Thanks


Solution

  • TO connect to WiFi AP needed to implement followed steps:

    1. Scan WiFi

      To be sure that you have appropriate AP. Bear in mind that you must provide password to secured AP. Suppose you know witch AP you prefer and now we are going to other step:

    2. Create new profile

      We need must support information about:

    What type AP should be: Open spot, WEP, WPA, (or WPA2), with shared-key authentication, WPA2-Enterprise (RADIUS Server authentication)

    Priority - Priority determines the preference given to a network by wpa_supplicant when choosing an access point with which to associate (I set default 1000)

    SSID - AP Name

    Password - if it's secured AP.

    Here is a snippets method demonstrating the technique:

    I used single enum TEncMode encMode for switch statement

    ....
    WifiConfiguration wc = new WifiConfiguration();
        wc.allowedAuthAlgorithms.clear();
        wc.allowedGroupCiphers.clear();
        wc.allowedKeyManagement.clear();
        wc.allowedPairwiseCiphers.clear();
        wc.allowedProtocols.clear();
    
        switch (encMode) {
        case ENC_WEP:
            // If password is empty, it should be left untouched
            if (!TextUtils.isEmpty(pswd)) {
    
                wc.wepKeys[0] = TextUtil.convertToQuotedString(pswd);
    
            }
    
            wc.wepTxKeyIndex = 0;
    
            wc.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
            wc.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
    
            wc.allowedKeyManagement.set(KeyMgmt.NONE);
    
            wc.allowedGroupCiphers.set(GroupCipher.WEP40);
            wc.allowedGroupCiphers.set(GroupCipher.WEP104);
            break;
    
        case ENC_WPA:
        case ENC_WPA2:
            wc.allowedGroupCiphers.set(GroupCipher.TKIP);
            wc.allowedGroupCiphers.set(GroupCipher.CCMP);
    
            wc.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
    
            wc.allowedPairwiseCiphers.set(PairwiseCipher.CCMP);
            wc.allowedPairwiseCiphers.set(PairwiseCipher.TKIP);
    
            wc.allowedProtocols.set(Protocol.RSN);
            wc.allowedProtocols.set(Protocol.WPA);
    
            // If password is empty, it should be left untouched
            if (!TextUtils.isEmpty(pswd)) {
                if (pswd.length() == 64) {
                    // Goes unquoted as hex
                    wc.preSharedKey = pswd;
                } else {
                    // Goes quoted as ASCII
                    wc.preSharedKey = TextUtil.convertToQuotedString(pswd);
                }
            }
            break;
    
            //      case ENC_WPA2_ENTERPRISE:
            ....
            //          break;
    
        default:
            wc.allowedKeyManagement.set(KeyMgmt.NONE);
            break;
        }
    
        // This is must be quoted according to the documentation 
        // http://developer.android.com/reference/android/net/wifi/WifiConfiguration.html#SSID
        wc.SSID = TextUtil.convertToQuotedString(ssid.toString());
    
        wc.hiddenSSID = false;
        wc.priority = prior;
        wc.BSSID = null;
    
    
        wc.status = WifiConfiguration.Status.ENABLED; 
    

    For now we configured new AP according to our requst. Now lets create it:

    1. Create new AP only

       ....
       int res = -1;
       WifiManager m_WifiManager = (WifiManager)m_context.getSystemService(Context.WIFI_SERVICE); 
      ....
              /** If profile exists, do nothing  */
          if(ifConnectionProfileExists(ssid) == true){
      
              Log.i(Constants.TAG, "createConnectionProfile :: " + "CREATE_PROFILE ssid=" + ssid  + " exists");
          }
          else{
              res = m_WifiManager.addNetwork(wc);
      
              Log.i(Constants.TAG, "createConnectionProfile :: " + " CREATE_PROFILE ssid=" + ssid  + " dosn't exist, addNetwork ... res = " + res);
      
              // Don't make to AP high priority to connect
              //m_WifiManager.enableNetwork(res, false);  
      
              m_WifiManager.saveConfiguration();
      
              if(res != -1){
                               // profile created                 
              }
              else{           
               // failed to add profile   
              }
          }
      

    if you skip this implementation, after turn WiFi off your created AP will dissapear m_WifiManager.saveConfiguration();

    So far so good, we can wait for android to connect to our new AP or we can do it by ourselves

    1. Create and connect to AP

       int res = -1;
      
          /** If profile exists, do nothing  */
          if(ifConnectionProfileExists(ssid) == true){
      
              res = getNetIdBySSID(ssid);
          }
          else{
              res = m_WifiManager.addNetwork(wc);             
          }
      
      
          // Don't make to AP high priority to connect
          boolean b = m_WifiManager.enableNetwork(res, true);      
      
          if(b == true){
      
              fixSupplicant();
      
              m_WifiManager.saveConfiguration();
      
              // start connect to AP
          }
          else{           
              // failed
          }
      
              ....
      
      private void fixSupplicant() {
          final SupplicantState state = m_WifiManager.getConnectionInfo().getSupplicantState();
          boolean isReconnectDone = false;
      
      if ((state == SupplicantState.SCANNING)
              || (state == SupplicantState.DISCONNECTED) 
              || (state == SupplicantState.DORMANT)) {
          isReconnectDone = m_WifiManager.reconnect();;
      
      }       
       }
      
      
         private boolean ifConnectionProfileExists(String ssid){
      
      List<WifiConfiguration> apProfiles = m_WifiManager.getConfiguredNetworks();
      
      // remove profile if exists:
      for (int i = 0; i < apProfiles.size(); i++) {
      
          final WifiConfiguration ap = apProfiles.get(i);
      
          if ((ap.SSID != null)) {        
              // try to find by SSID
              if (TextUtils.equals(ap.SSID), ssid) {                  
                  return true;
              }
          }               
      }
      
      return false;
       }
      

    Enum TEncMode

    /**
    * Represents encryption types modes of access points
    */
    public enum TEncMode {
    
    /**
     * No encryption (open spot)
     */
    ENC_NONE(0),
    
    /*
     * General encryption
     */
    ENC_UNKNOWN(1),
    
    /**
     * WEP
     */
    ENC_WEP(2),
    
    /**
     * WPA
     */
    ENC_WPA(3),
    
    /**
     * WPA (or WPA2), with shared-key authentication
     */
    ENC_WPA2(4),
    
    /**
     * WPA2-Enterprise (RADIUS Server authentication).
     */
    ENC_WPA2_ENTERPRISE(5)
    ;
    
    public static TEncMode
    FromIntToEnum(
        int value ) throws Exception
    {
        for ( TEncMode c : TEncMode.values() ) {
            if ( c.mId == value ) {
                return c;
            }
        }
    
        throw new AgException( new StringBuilder("Illegal TEncMode: ").append(value).toString() );
    }
    
    public int
    FromEnumToInt() {
        return mId;
    }
    
    private TEncMode( int id ){
        mId = id;
    }
    
    private int mId;
    }
    

    That's all. For sure you can listen on WiFi state changed to catch CONNECTED event. Because we don't know how long it will take to device to connect to your AP. But we disabled all other APs and enabled new one. After we can get HTTP response for example from google to be sure that our AP has internet.

    Asked me to add this method:

        /**
     * Surround the given string in quotes.
     * 
     * @param string The text to surround in quotes.
     * @return string wrapped with quotes.
     */
    static public String convertToQuotedString(String string){
    
        if (string==null) {
            string = "";
        }
        empty(workBuffer);
        workBuffer.append("\"");
        workBuffer.append(string);
        workBuffer.append("\"");
    
        return workBuffer.toString();
    }