title: android turning on wifi programmatically
body: <p>I am trying to turn add a wifi network programmatically and to connect to that network.</p>
  
  <p>My code works fine if the wi-fi is already turned on.</p>
  
  <p>If wi-fi is off, what i see wifimanager.addtonetwork() fails and when i see the wifi settings for the phone, i can see the status as scanning</p>
  
  <p>If i try to connect again it works fine.</p>
  
  <p>Please see code below.
  Please help</p>
  
  <pre><code>private int changeNetwork(NetworkSetting setting) {
      // If the SSID is empty, throw an error and return
      if (setting.getSsid() == null || setting.getSsid().length() == 0) {
          return doError(R.string.wifi_ssid_missing);
      }
      // If the network type is invalid
      if (setting.getNetworkType() == NetworkType.NETWORK_INVALID) {
          return doError(R.string.wifi_type_incorrect);
      }
  
      // If the password is empty, this is an unencrypted network
      if (setting.getPassword() == null
              || setting.getPassword().length() == 0
              || setting.getNetworkType() == null
              || setting.getNetworkType() == NetworkType.NETWORK_NOPASS) {
          return changeNetworkUnEncrypted(setting);
      }
      if (setting.getNetworkType() == NetworkType.NETWORK_WPA) {
          return changeNetworkWPA(setting);
      } else {
          return changeNetworkWEP(setting);
      }
  }
  
  private int doError(int resource_string) {
      statusView.setText(resource_string);
      // Give up on the connection
      wifiManager.disconnect();
      if (networkId &gt; 0) {
          wifiManager.removeNetwork(networkId);
          networkId = -1;
      }
      if (receiverRegistered) {
          unregisterReceiver(wifiReceiver);
          receiverRegistered = false;
      }
      return -1;
  }
  
  private WifiConfiguration changeNetworkCommon(NetworkSetting input) {
      statusView.setText(R.string.wifi_creating_network);
      Log.d(TAG, "Adding new configuration: \nSSID: " + input.getSsid()
              + "\nType: " + input.getNetworkType());
      WifiConfiguration config = new WifiConfiguration();
  
      config.allowedAuthAlgorithms.clear();
      config.allowedGroupCiphers.clear();
      config.allowedKeyManagement.clear();
      config.allowedPairwiseCiphers.clear();
      config.allowedProtocols.clear();
  
      // Android API insists that an ascii SSID must be quoted to be correctly
      // handled.
      config.SSID = NetworkUtil.convertToQuotedString(input.getSsid());
      config.hiddenSSID = true;
      return config;
  }
  
  private int requestNetworkChange(WifiConfiguration config) {
      statusView.setText(R.string.wifi_changing_network);
      return updateNetwork(config, false);
  }
  
  // Adding a WEP network
  private int changeNetworkWEP(NetworkSetting input) {
      WifiConfiguration config = changeNetworkCommon(input);
      String pass = input.getPassword();
      if (NetworkUtil.isHexWepKey(pass)) {
          config.wepKeys[0] = pass;
      } else {
          config.wepKeys[0] = NetworkUtil.convertToQuotedString(pass);
      }
      config.allowedAuthAlgorithms
              .set(WifiConfiguration.AuthAlgorithm.SHARED);
      config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
      config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
      config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
      config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
      config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
      config.wepTxKeyIndex = 0;
      return requestNetworkChange(config);
  }
  
  // Adding a WPA or WPA2 network
  private int changeNetworkWPA(NetworkSetting input) {
      WifiConfiguration config = changeNetworkCommon(input);
      String pass = input.getPassword();
      // Hex passwords that are 64 bits long are not to be quoted.
      if (HEX_DIGITS_64.matcher(pass).matches()) {
          Log.d(TAG, "A 64 bit hex password entered.");
          config.preSharedKey = pass;
      } else {
          Log.d(TAG, "A normal password entered: I am quoting it.");
          config.preSharedKey = NetworkUtil.convertToQuotedString(pass);
      }
      config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
      // For WPA
      config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
      // For WPA2
      config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
      config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
      config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
      config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
      return requestNetworkChange(config);
  }
  
  // Adding an open, unsecured network
  private int changeNetworkUnEncrypted(NetworkSetting input) {
      Log.d(TAG, "Empty password prompting a simple account setting");
      WifiConfiguration config = changeNetworkCommon(input);
      config.wepKeys[0] = "";
      config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
      config.wepTxKeyIndex = 0;
      return requestNetworkChange(config);
  }
  
  /**
   * If the given ssid name exists in the settings, then change its password
   * to the one given here, and save
   * 
   * @param ssid
   */
  private WifiConfiguration findNetworkInExistingConfig(String ssid) {
      List&lt;WifiConfiguration&gt; existingConfigs = wifiManager
              .getConfiguredNetworks();
      Log.i("Start comparing","Size "+existingConfigs.size() );
      for (WifiConfiguration existingConfig : existingConfigs) {
          Log.i("Compare with SSID", ssid + existingConfig.SSID);
          if (existingConfig.SSID.equals(ssid)) {
              Log.i("Compare success with SSID", ssid + existingConfig.SSID);
              return existingConfig;
          }
      }
      return null;
  }
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
  
      Intent intent = getIntent();
  /*  if (intent == null
              || !intent.getAction().equals(Intents.WifiConnect.ACTION)) {
          finish();
          return;
      } */
  
      String ssid = intent.getStringExtra("ssid");
      String password = intent.getStringExtra("password");
      String networkType = intent.getStringExtra("type");
      setContentView(R.layout.network);
      statusView = (TextView) findViewById(R.id.networkStatus);
  
      NetworkType networkT;
      if ("WPA".equals(networkType)) {
          networkT = NetworkType.NETWORK_WPA;
      } else if ("WEP".equals(networkType)) {
          networkT = NetworkType.NETWORK_WEP;
      } else if ("nopass".equals(networkType)) {
          networkT = NetworkType.NETWORK_NOPASS;
      } else {
          networkT = NetworkType.NETWORK_INVALID;
      }
  
      // This is not available before onCreate
      wifiManager = (WifiManager) this.getSystemService(WIFI_SERVICE);
      // Start WiFi, otherwise nothing will work
      wifiManager.setWifiEnabled(true);
  
      // So we know when the network changes
      wifiReceiver = new WifiReceiver(wifiManager, this, statusView, ssid);
  
      // The order matters!
      mWifiStateFilter = new IntentFilter(
              WifiManager.WIFI_STATE_CHANGED_ACTION);
      mWifiStateFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
      mWifiStateFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
      mWifiStateFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
      registerReceiver(wifiReceiver, mWifiStateFilter);
      receiverRegistered = true;
  
      if (password == null) {
          password = "";
      }
      Log.d(TAG, "Adding new configuration: \nSSID: " + ssid + "Type: "
              + networkT);
      NetworkSetting setting = new NetworkSetting(ssid, password, networkT);
  
      changeNetwork(setting);
  }
  
  @Override
  public void onPause() {
      super.onPause();
      if (receiverRegistered) {
          unregisterReceiver(wifiReceiver);
          receiverRegistered = false;
      }
  }
  
  @Override
  public void onResume() {
      super.onResume();
      if (wifiReceiver != null &amp;&amp; mWifiStateFilter != null
              &amp;&amp; !receiverRegistered) {
          registerReceiver(wifiReceiver, mWifiStateFilter);
          receiverRegistered = true;
      }
  }
  
  @Override
  protected void onDestroy() {
      if (wifiReceiver != null) {
          if (receiverRegistered) {
              unregisterReceiver(wifiReceiver);
              receiverRegistered = false;
          }
          wifiReceiver = null;
      }
      super.onDestroy();
  }
  
  /**
   * Update the network: either create a new network or modify an existing
   * network
   * 
   * @param config
   *            the new network configuration
   * @param disableOthers
   *            true if other networks must be disabled
   * @return network ID of the connected network.
   */
  private int updateNetwork(WifiConfiguration config, boolean disableOthers) {
      WifiConfiguration found = findNetworkInExistingConfig(config.SSID);
      wifiManager.disconnect();
      if (found == null) {
          Log.i("WIFI","SSID NOT FOUND");
          statusView.setText(R.string.wifi_creating_network);
      } else {
          statusView.setText(R.string.wifi_modifying_network);
          Log.d(TAG, "Removing network " + found.networkId);
          wifiManager.removeNetwork(found.networkId);
          wifiManager.saveConfiguration();
      }
      networkId = wifiManager.addNetwork(config);
      Log.d(TAG, "Inserted/Modified network " + networkId);
      if (networkId &lt; 0) {
          wifiManager.setWifiEnabled(true);
          networkId = wifiManager.addNetwork(config);
          Log.d(TAG, "Again Inserted/Modified network " + networkId);
          return FAILURE_NO_NETWORK_ID;
      }
  
      // Try to disable the current network and start a new one.
      if (!wifiManager.enableNetwork(networkId, disableOthers)) {
          networkId = FAILURE_NO_NETWORK_ID;
          return FAILURE_NO_NETWORK_ID;
      }
      errorCount = 0;
      wifiManager.reassociate();
      return networkId;
  }
  </code></pre>
  
  <p>Here is my working code : ( its different from my previous code )</p>
  
  <pre><code>    package com.idg.project.utils;
  
  
  import java.util.List;
  import java.util.regex.Pattern;
  
  import android.net.wifi.WifiConfiguration;
  import android.net.wifi.WifiManager;
  import android.util.Log;
  
  
  
  /**
   * @author Vikram Aggarwal
   * @author Sean Owen
   */
  public final class WifiConfigManager {
  
    private static final String TAG = WifiConfigManager.class.getSimpleName();
  
    private static final Pattern HEX_DIGITS = Pattern.compile("[0-9A-Fa-f]+");
  
    private WifiConfigManager() {
    }
  
    public static void configure(final WifiManager wifiManager, 
                                 final String ssid, 
                                 final String password, 
                                 final String networkTypeString) {
      Runnable configureRunnable = new Runnable() {
        public void run() {
          // Start WiFi, otherwise nothing will work
          if (!wifiManager.isWifiEnabled()) {
            Log.i(TAG, "Enabling wi-fi...");
            if (wifiManager.setWifiEnabled(true)) {
              Log.i(TAG, "Wi-fi enabled");
            } else {
              Log.w(TAG, "Wi-fi could not be enabled!");
              return;
            }
            // This happens very quickly, but need to wait for it to enable. A little busy wait?
            int count = 0;
            while (!wifiManager.isWifiEnabled()) {
              if (count &gt;= 10) {
                Log.i(TAG, "Took too long to enable wi-fi, quitting");
                return;
              }
              Log.i(TAG, "Still waiting for wi-fi to enable...");
              try {
                Thread.sleep(1000L);
              } catch (InterruptedException ie) {
                // continue
              }
              count++;
            }
          }
          NetworkType networkType = NetworkType.forIntentValue(networkTypeString);
          if (networkType == NetworkType.NO_PASSWORD) {
            changeNetworkUnEncrypted(wifiManager, ssid);
          } else {
            if (password == null || password.length() == 0) {
              throw new IllegalArgumentException();
            }
            if (networkType == NetworkType.WEP) {
              changeNetworkWEP(wifiManager, ssid, password);
            } else if (networkType == NetworkType.WPA) {
              changeNetworkWPA(wifiManager, ssid, password);
            }        }
        }
      };
      new Thread(configureRunnable).start();
    }
  
    /**
     * Update the network: either create a new network or modify an existing network
     * @param config the new network configuration
     * @return network ID of the connected network.
     */
    private static void updateNetwork(WifiManager wifiManager, WifiConfiguration config) {
      Integer foundNetworkID = findNetworkInExistingConfig(wifiManager, config.SSID);
      if (foundNetworkID != null) {
        Log.i(TAG, "Removing old configuration for network " + config.SSID);
        wifiManager.removeNetwork(foundNetworkID);
        wifiManager.saveConfiguration();
      }
      int networkId = wifiManager.addNetwork(config);
      if (networkId &gt;= 0) {
        // Try to disable the current network and start a new one.
        if (wifiManager.enableNetwork(networkId, true)) {
          Log.i(TAG, "Associating to network " + config.SSID);
          wifiManager.saveConfiguration();
        } else {
          Log.w(TAG, "Failed to enable network " + config.SSID);
        }
      } else {
        Log.w(TAG, "Unable to add network " + config.SSID);
      }
    }
  
    private static WifiConfiguration changeNetworkCommon(String ssid) {
      WifiConfiguration config = new WifiConfiguration();
      config.allowedAuthAlgorithms.clear();
      config.allowedGroupCiphers.clear();
      config.allowedKeyManagement.clear();
      config.allowedPairwiseCiphers.clear();
      config.allowedProtocols.clear();
      // Android API insists that an ascii SSID must be quoted to be correctly handled.
      config.SSID = quoteNonHex(ssid);
      return config;
    }
  
    // Adding a WEP network
    private static void changeNetworkWEP(WifiManager wifiManager, String ssid, String password) {
      WifiConfiguration config = changeNetworkCommon(ssid);
      config.wepKeys[0] = quoteNonHex(password, 10, 26, 58);
      config.wepTxKeyIndex = 0;
      config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
      config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
      config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
      config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
      config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
      config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
      updateNetwork(wifiManager, config);
    }
  
    // Adding a WPA or WPA2 network
    private static void changeNetworkWPA(WifiManager wifiManager, String ssid, String password) {
      WifiConfiguration config = changeNetworkCommon(ssid);
      // Hex passwords that are 64 bits long are not to be quoted.
      config.preSharedKey = quoteNonHex(password, 64);
      config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
      config.allowedProtocols.set(WifiConfiguration.Protocol.WPA); // For WPA
      config.allowedProtocols.set(WifiConfiguration.Protocol.RSN); // For WPA2
      config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
      config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
      config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
      config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
      config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
      config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
      updateNetwork(wifiManager, config);
    }
  
    // Adding an open, unsecured network
    private static void changeNetworkUnEncrypted(WifiManager wifiManager, String ssid) {
      WifiConfiguration config = changeNetworkCommon(ssid);
      config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
      updateNetwork(wifiManager, config);
    }
  
    private static Integer findNetworkInExistingConfig(WifiManager wifiManager, String ssid) {
      List&lt;WifiConfiguration&gt; existingConfigs = wifiManager.getConfiguredNetworks();
      for (WifiConfiguration existingConfig : existingConfigs) {
        if (existingConfig.SSID.equals(ssid)) {
          return existingConfig.networkId;
        }
      }
      return null;
    }
  
    private static String quoteNonHex(String value, int... allowedLengths) {
      return isHexOfLength(value, allowedLengths) ? value : convertToQuotedString(value);
    }
  
    /**
     * Encloses the incoming string inside double quotes, if it isn't already quoted.
     * @param string the input string
     * @return a quoted string, of the form "input".  If the input string is null, it returns null
     * as well.
     */
    private static String convertToQuotedString(String string) {
      if (string == null || string.length() == 0) {
        return null;
      }
      // If already quoted, return as-is
      if (string.charAt(0) == '"' &amp;&amp; string.charAt(string.length() - 1) == '"') {
        return string;
      }
      return '\"' + string + '\"';
    }
  
    /**
     * @param value input to check
     * @param allowedLengths allowed lengths, if any
     * @return true if value is a non-null, non-empty string of hex digits, and if allowed lengths are given, has
     *  an allowed length
     */
    private static boolean isHexOfLength(CharSequence value, int... allowedLengths) {
      if (value == null || !HEX_DIGITS.matcher(value).matches()) {
        return false;
      }
      if (allowedLengths.length == 0) {
        return true;
      }
      for (int length : allowedLengths) {
        if (value.length() == length) {
          return true;
        }
      }
      return false;
    }
  
  }
  
  
  
  
  
  
  
  
  
      package com.idg.project.utils;
  
  
  
  enum NetworkType {
  
    WEP,
    WPA,
    NO_PASSWORD;
  
    static NetworkType forIntentValue(String networkTypeString) {
      if (networkTypeString == null) {
        return NO_PASSWORD;
      }
      if ("WPA".equals(networkTypeString)) {
        return WPA;
      }
      if ("WEP".equals(networkTypeString)) {
        return WEP;
      }
      if ("nopass".equals(networkTypeString)) {
        return NO_PASSWORD;
      }
      throw new IllegalArgumentException(networkTypeString);
    }
  
  }
  </code></pre>