title: Connecting to Wifi Programatically in Android does not work in Android M
body: <p>I am trying to create an app where the app will connect to a Wi-Fi.
  It is connecting to Wifi in all Android devices below android 6. But in Android 6, it will connect and drop after sometime say 10-20 seconds. Below is the complete Wifi Manager code.</p>
  
  <p>Am I doing anything wrong in the below code.
  I am asking for runtime LOCATION permission and also will ask to switch on the location.  All manifest permissions are added in Manifest.
  ACCESS_WIFI_STATE, CHANGE_WIFI_STATE, CHANGE_NETWORK_STATE,ACCESS_NETWORK_STATE,
  ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION.</p>
  
  <pre><code>public class WifiManager implements Handler.Callback {
  
      private static final String TAG = WifiManager.class.getSimpleName();
      private Handler handler;
      private Context reactContext;
  
      private static final String WIFI_EVENT_NAME = "WiFiStatusEvent";
      private static final String WIFI_STATUS = "WiFiStatus";
      private static final int STATE_UNKNOWN = 0;
      private static final int STATE_WIFI_OFF = 1;
      private static final int STATE_WIFI_ON = 2;
      private static final int STATE_SSID_VISIBLE = 3;
      private static final int STATE_SSID_CONFIGURED = 4;
      private static final int STATE_SSID_ASSOCIATING = 5;
      private static final int STATE_SSID_ASSOCIATED = 6;
      // A slight delay after the wifi says it is connected before we return to the calling app.
      // (Sometimes the wifi isn't quite ready yet, even though it says it is)
      private static final long DELAY_AFTER_CONNECTION_TIMEOUT = 1000 * 2;
      // ESSID connect default timeout
      private static final long DEFAULT_TARGET_NETWORK_CONNECT_TIMEOUT = 15 * 1000;
  
      // Internal connection progress states
      private int state = STATE_UNKNOWN;
      // The system wifi manager
      private android.net.wifi.WifiManager wifi;
      // The application context to use for system functions
      private String targetSSID = null;
      // The given callback to message when we are done
      private Handler timeoutHandler = null;
      private static long timeout = 500000;
  
      public WifiManager(Context reactContext) {
          this.reactContext = reactContext;
          wifi = (android.net.wifi.WifiManager) reactContext.getApplicationContext().getSystemService(WIFI_SERVICE);
      }
  
      public void connectToHost(Context context, String host, String password) {
          WifiConfiguration wc = new WifiConfiguration();
  
          wc.SSID = host;
          //wc.preSharedKey = password;
  
          int netId = wifi.addNetwork(wc);
  
          try {
              wifi.enableNetwork(netId, true);
              wifi.setWifiEnabled(true);
  
              System.out.println("enabled network");
          } catch (Exception e) {
              e.printStackTrace();
              System.out.println(e.getMessage());
          }
      }
  
  
      public void connectToHost2(Context context, String host, String password) {
          WifiConfiguration wc = new WifiConfiguration();
  
          wc.SSID = host;
          //wc.preSharedKey = password;
          wc.status = WifiConfiguration.Status.ENABLED;
          wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
          wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA); // For WPA
          wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN); // For WPA2
          wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
          wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
          wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
          wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
          wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
          wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
  
  
          int netId = wifi.addNetwork(wc);
          WifiConfiguration wifiConfig = setWifiConfiguration(targetSSID, WifiConfiguration.KeyMgmt.NONE);
  
          int networkId = wifi.addNetwork(wifiConfig);
          logInfo(TAG, "networkId :: " + networkId);
  
          wifi.saveConfiguration();
  
  
          try {
              wifi.enableNetwork(netId, true);
              wifi.setWifiEnabled(true);
  
              System.out.println("enabled network");
          } catch (Exception e) {
              e.printStackTrace();
              System.out.println(e.getMessage());
          }
      }
  
      public void connectToWifi() {
  
          try {
              WifiConfiguration wc = new WifiConfiguration();
              WifiInfo wifiInfo = wifi.getConnectionInfo();
              wc.SSID = "\"WIFI_SSID\"";
              wc.priority = 1;
              //wc.preSharedKey = "\"PASSWORD\"";
              wc.status = WifiConfiguration.Status.ENABLED;
              wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
              wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
              int netId = wifi.addNetwork(wc);
              if (netId == -1) {
                  netId = getExistingNetworkId(wc.SSID);
              }
              wifi.disconnect();
              wifi.enableNetwork(netId, true);
              wifi.reconnect();
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  
      private int getExistingNetworkId(String SSID) {
          List&lt;WifiConfiguration&gt; configuredNetworks = wifi.getConfiguredNetworks();
          if (configuredNetworks != null) {
              for (WifiConfiguration existingConfig : configuredNetworks) {
                  if (existingConfig.SSID.equals(SSID)) {
                      return existingConfig.networkId;
                  }
              }
          }
          return -1;
      }
  
      public void connectToWifi(String wifiSSID) {
  
  
          logInfo(TAG, "Connecting to " + wifiSSID);
  
          if (null == handler) {
              handler = new Handler(this);
          }
  
          if (null == wifiSSID || wifiSSID.isEmpty()) {
              return;
          }
  
          displayLocationSettingsRequest(reactContext);
  
          this.targetSSID = wifiSSID;
  
          //removeNetwork();
          connectToTargetNetwork();
  
  
      }
  
      //@ReactMethod
      public void isConnected(String wifiSSID) {
          this.targetSSID = wifiSSID;
  
      }
  
      @Override
      public boolean handleMessage(Message msg) {
  
          if (null == msg) {
              logError(TAG, "Callback, error");
              return false;
          }
  
          if (null == msg.obj) {
              logError(TAG, "Callback, error");
              return false;
          }
  
          WifiStatus wifiStatus = (WifiStatus) msg.obj;
          if (null != wifiStatus) {
              logInfo(TAG, "ID :: " + wifiStatus.getId());
          }
          return false;
      }
  
      /**
       * WIFI state callback - Listening for WIFI on/off transitions
       */
      private BroadcastReceiver wifiStateReceiver = new BroadcastReceiver() {
          public void onReceive(Context c, Intent intent) {
  
              logInfo(TAG, "WifiStateReceiver - onReceive" + intent.getPackage());
  
              ConnectivityManager cm = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
              NetworkInfo currentNetworkInfo = cm.getActiveNetworkInfo();
  
              if (currentNetworkInfo != null &amp;&amp; "WIFI".equals(currentNetworkInfo.getTypeName())) {
  
                  logInfo(TAG, "NetworkInfo - TypeName = " + currentNetworkInfo.getTypeName() + ", state = " + currentNetworkInfo.getState());
  
                  if (currentNetworkInfo.getState() == NetworkInfo.State.CONNECTED) {
  
                      if (isConnectedToTargetNetwork()) {
                          sendCallbackMessage(handler, WifiStatus.ASSOCIATED);
                          delayBeforeFinish();
                          return;
                      }
  
  
                  }
  
                  // We are connected
                  if (!isConnectedToTargetNetwork()) {
                      state = STATE_WIFI_ON;
                      logInfo(TAG, "Starting wifi scan...");
                      wifi.startScan();
                  }
              }
          }
      };
  
      /**
       * WIFI state callback - Listening for network scan completion
       */
      private BroadcastReceiver wifiScanResultsReceiver = new BroadcastReceiver() {
          public void onReceive(Context c, Intent intent) {
  
              Logger.logWarning(TAG, "WifiScanResultsReceiver - onReceive");
  
              // Don't care unless wifi is on
              if (state != STATE_WIFI_ON) {
                  return;
              }
  
              // Check if we are already connected to target network
              if (isConnectedToTargetNetwork()) {
                  sendCallbackMessage(handler, WifiStatus.ASSOCIATED);
                  delayBeforeFinish();
                  return;
              }
  
              // Check if the target network showed up in the scan
              if (isOurNetworkVisible()) {
                  logInfo(TAG, "Scan found our ESSID:" + targetSSID);
                  connectToVisibleNetwork();
              } else {
                  logInfo(TAG, "Scan DID NOT FIND ESSID:" + targetSSID);
              }
  
          }
      };
  
  
      /**
       * method to return the current WIFI connectivity state
       *
       * @param targetSSID the network SSID we are hoping to be associated with
       * @return connection status
       */
      public WifiStatus getStatus(String targetSSID) {
          // Get a temporary WiFiManager instance since this is a static method
  
          // Check if wifi is on
          if (!wifi.isWifiEnabled()) {
              return WifiStatus.WIFI_OFF;
          }
  
          // Check if associated to anything
          WifiInfo wifiInfo = wifi.getConnectionInfo();
          if (wifiInfo == null || wifiInfo.getSSID() == null) {
              return WifiStatus.WIFI_ON;
          }
  
          // Check if associated to given SSID
          if (wifiInfo.getSSID().equals(targetSSID)) {
              return WifiStatus.ASSOCIATED;
          }
  
          // Check if given SSID is visible
          List&lt;ScanResult&gt; wifiList = wifi.getScanResults();
          for (ScanResult info : wifiList) {
              if (targetSSID.equals(info.SSID)) {
                  return WifiStatus.SSID_VISIBLE;
              }
          }
  
          return WifiStatus.SSID_NOT_VISIBLE;
  
      }
  
      /**
       * Method to turn off WiFi
       *
       * @param context the callers application context
       * @return true if successful
       */
      public boolean turnOffWifi(Context context) {
          // Get a temporary WiFiManager instance since this is a static method
          return wifi.setWifiEnabled(false);
      }
  
      /**
       * Sends a message to the callback.
       *
       * @param callback the callback to send to
       */
      private static void sendCallbackMessage(Handler callback, WifiStatus status) {
          if (null != callback) {
              Message message = callback.obtainMessage();
              if (null != message) {
                  message.obj = status;
                  callback.sendMessage(message);
              }
          }
      }
  
      /**
       * Connects to the given ESSID.  Turns on WiFi if necessary.
       * Once the operation is complete (whether successful or not),
       * it sends a message to the given Handler with the state of the WiFi connection.
       */
      public void connectToTargetNetwork() {
  
          // Add timeout override to get out no matter what happens...
          timeoutHandler = new Handler();
          timeoutHandler.postDelayed(masterCompletionTimeout, timeout);
  
          state = STATE_UNKNOWN;
  
          // Check if we are already connected to target network
          if (isConnectedToTargetNetwork()) {
              sendCallbackMessage(handler, WifiStatus.ASSOCIATED);
              return;
          }
  
          registerReceivers();
  
          // Check if WIFI is turned on
          // Not enabled, turn it on!
          if (!wifi.isWifiEnabled()) {
              logInfo(TAG, "Enabling WIFI...");
              state = STATE_WIFI_OFF;
              boolean success = wifi.setWifiEnabled(true);
              if (!success) {
                  sendCallbackMessage(handler, WifiStatus.WIFI_OFF);
              }
              // Wait for connection callback
              return;
          }
  
          // We are connected, check if target SSID is visible
          state = STATE_WIFI_ON;
  
          logInfo(TAG, "Starting wifi scan...");
          wifi.startScan();
  
  
      }
  
      public void registerReceivers() {
          // Register system WIFI state callbacks
          reactContext.getApplicationContext().registerReceiver(wifiStateReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
          reactContext.getApplicationContext().registerReceiver(wifiScanResultsReceiver, new IntentFilter(android.net.wifi.WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
      }
  
      /**
       * Perform internal cleanup before returning response to caller
       */
      public void cleanupConnectToTargetNetwork() {
          logInfo(TAG, "cleanupConnectToTargetNetwork");
  
          // Unregister all internal WiFi state receivers
          if (reactContext.getApplicationContext() != null) {
              // Unregister all our WIFI status receivers
              try {
                  if (null != wifiStateReceiver) {
                      reactContext.getApplicationContext().unregisterReceiver(wifiStateReceiver);
                  }
              } catch (Exception e) {
                  logError(TAG, e.getMessage());
              }
  
              try {
                  if (null != wifiScanResultsReceiver) {
                      reactContext.getApplicationContext().unregisterReceiver(wifiScanResultsReceiver);
                  }
              } catch (Exception e) {
                  logError(TAG, e.getMessage());
              }
          }
  
          // Cancel our master timeout
          if (timeoutHandler != null) {
              try {
                  timeoutHandler.removeCallbacks(masterCompletionTimeout);
              } catch (Exception e) {
                  logError(TAG, e.getMessage());
              }
  
              timeoutHandler = null;
          }
  
          try {
              state = STATE_UNKNOWN;
              // Get the final WiFi status and send it back to the caller
              WifiStatus status = getStatus(targetSSID);
              logInfo(TAG, "cleanupConnectToTargetNetwork - WiFi status=" + status.getName());
              sendCallbackMessage(handler, status);
          } catch (Exception e) {
              logError(TAG, "Error IN Wifi :: " + e);
          }
  
      }
  
      /**
       * Provides a slight delay before sending a results message to the caller.
       * This method is used when the requested network connection has been made successfully.
       * We have seen that when the OS reports the WiFi is ready, it might actually not be for a couple more seconds.
       * So we impart a slight delay to cover this.
       */
      private void delayBeforeFinish() {
          if (timeoutHandler != null) {
              timeoutHandler.removeCallbacks(masterCompletionTimeout);
          }
          if (timeoutHandler == null) {
              timeoutHandler = new Handler();
          }
          timeoutHandler.postDelayed(masterCompletionTimeout, DELAY_AFTER_CONNECTION_TIMEOUT);
      }
  
      /**
       * Connect to our target SSID.
       * A prerequisite to calling this function is that the SSID is visible from a network scan.
       */
      private void connectToVisibleNetwork() {
          logInfo(TAG, "connectToVisibleNetwork");
  
          // SSID is visible, check if it is configured
          state = STATE_SSID_VISIBLE;
  
          if (state == STATE_SSID_ASSOCIATING) {
              logError(TAG, "Associating now...");
              return;
          }
  
          // Check if the target SSID is configured on this device
          int networkId = isNetworkConfigured(targetSSID);
          logInfo(TAG, "Our network is configured returned:" + networkId);
          if (networkId &lt; 0) {
              // Network not configured, Add the network
              logInfo(TAG, "Adding our network to configuration...");
              WifiConfiguration wifiConfig = setWifiConfiguration(targetSSID, WifiConfiguration.KeyMgmt.NONE);
  
              networkId = wifi.addNetwork(wifiConfig);
              logInfo(TAG, "addNetwork returned: " + networkId);
              if (networkId &lt; 0) {
                  return;
              }
  
              // Network added, save the changes
              wifi.saveConfiguration();
          }
  
          setWifiConfiguration(targetSSID, WifiConfiguration.KeyMgmt.NONE);
  
          wifi.disconnect();
          //wifi.saveConfiguration();
          // Network is configured on this device
          state = STATE_SSID_CONFIGURED;
  
          // Connect to network
          state = STATE_SSID_ASSOCIATING;
          boolean success = wifi.enableNetwork(networkId, true);
  
          //c2();
          wifi.reconnect();
  
  //        if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.LOLLIPOP) {
  //            ConnectivityManager.setProcessDefaultNetwork(networkId);
  //        }
          //ConnectivityManager.
          logInfo(TAG, "Enable our SSID returned:" + success);
  
          if (success) {
              logInfo(TAG, "connectToVisibleNetwork, Success...");
          }
  
          //connectToHost2(getReactApplicationContext(), targetSSID, "");
          return;
      }
  
  
      @NonNull
      private WifiConfiguration setWifiConfiguration(String targetSSID, int none) {
          WifiConfiguration wc = new WifiConfiguration();
          wc.SSID = formatSSIDWithQuotes(targetSSID);
          wc.hiddenSSID = false;
        /*  wifiConfig.priority = 1;
          wifiConfig.allowedKeyManagement.set(none);
          wifiConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
          wifiConfig.allowedKeyManagement.set(none);
          wifiConfig.status = WifiConfiguration.Status.ENABLED;*/
          wc.status = WifiConfiguration.Status.ENABLED;
          wc.priority = 1;
          wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
          wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
          wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
  
          wc.allowedAuthAlgorithms.set(0);
          wc.status = 2;
  
          wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
          wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
          wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
          wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
          wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
          wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
          wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
          wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
          assignHighestPriority(wc);
          //wifi.updateNetwork(wc);
          return wc;
      }
  
      /**
       * Check if our target SSID is visible to the WIFI radio
       *
       * @return true if visible
       */
      public boolean isOurNetworkVisible() {
  
          // Get a list of visible SSID's and iterate through them
          List&lt;ScanResult&gt; wifiList = wifi.getScanResults();
          for (ScanResult info : wifiList) {
              Logger.logWarning(TAG, "Scan found ESSID:" + info.SSID + ", Strength :: " + info.level);
              // Check if each one is ours
              if (null != targetSSID &amp;&amp; targetSSID.equals(info.SSID)) {
                  return true;
              }
          }
          return false;
      }
  
      /* Check the strength of the WiFi
          0-3, 3=good
       */
      public boolean isInRange() {
          // Get a list of visible SSID's and iterate through them
          List&lt;ScanResult&gt; wifiList = wifi.getScanResults();
          for (ScanResult info : wifiList) {
              if (null != targetSSID &amp;&amp; targetSSID.equals(info.SSID)) {
                  int rssi = wifi.getConnectionInfo().getRssi();
                  int level = wifi.calculateSignalLevel(rssi, 3);
                  Logger.logWarning(TAG, "Scan found ESSID:" + info.SSID + ", Strength :: " + info.level + " , Calculated Level :: " + level);
                  return level &gt; 0;
              }
          }
          return false;
      }
  
      /**
       * Check if we are connected to the target SSID
       *
       * @return
       */
      private boolean isConnectedToTargetNetwork() {
          try {
              wifi = (android.net.wifi.WifiManager) reactContext.getApplicationContext().getSystemService(WIFI_SERVICE);
              if (null == wifi) {
                  return false;
              }
              if (!wifi.isWifiEnabled()) {
                  return false;
              }
              WifiInfo wifiInfo = wifi.getConnectionInfo();
  
              if (null != targetSSID) {
                  targetSSID = targetSSID.replaceAll("\"", "");
              }
              String ssid = wifiInfo.getSSID();
              if (null != ssid) {
                  ssid = ssid.replaceAll("\"", "");
              }
              return wifiInfo != null &amp;&amp; wifiInfo.getSSID() != null &amp;&amp; ssid.equals(targetSSID);
          } catch (Exception e) {
              logError(TAG, "&lt;&lt; isConnectedToTargetNetwork &gt;&gt; " + e);
              return false;
          }
      }
  
      /**
       * Check if the given network is configured on this device
       *
       * @param ssid the SSID to check
       * @return the networkId of this SSID or -1 if not found
       */
      private int isNetworkConfigured(String ssid) {
          logInfo(TAG, "isNetworkConfigured for &gt;" + ssid + "&lt;");
  
          // The SSID's returned by the system have quotes around them
          String formattedSSID = formatSSIDWithQuotes(ssid);
  
          try {
              // Get the configured networks (SSID's) and iterate though them
              List&lt;WifiConfiguration&gt; networksList = wifi.getConfiguredNetworks();
              for (WifiConfiguration config : networksList) {
                  logInfo(TAG, "Config - essid =: " + config.SSID + ", id =" + config.networkId);
  
                  // Is this our SSID?
                  if (formattedSSID.equals(config.SSID)) {
                      logInfo(TAG, "Network IS configured - essid=:" + config.SSID + ", id=" + config.networkId);
                      wifi.saveConfiguration();
                      // Return the internal network id of this SSID
                      return config.networkId;
                  }
              }
          } catch (Exception e) {
              logInfo(TAG, "isNetworkConfigured exception - " + e.getMessage());
          }
  
          // The given SSID was not found
          return -1;
      }
  
      private String formatSSIDWithQuotes(String ssid) {
          return "\"" + ssid + "\"";
      }
  
      public static void displayLocationSettingsRequest(final Context activity) {
  
          final Message message = new Message();
  
          GoogleApiClient googleApiClient = new GoogleApiClient.Builder(activity)
                  .addApi(LocationServices.API).build();
          googleApiClient.connect();
  
          LocationRequest locationRequest = LocationRequest.create();
          locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
          locationRequest.setInterval(30 * 1000);
          locationRequest.setFastestInterval(5 * 1000);
  
          LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                  .addLocationRequest(locationRequest);
          builder.setAlwaysShow(true);
  
          PendingResult&lt;LocationSettingsResult&gt; result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
          result.setResultCallback(new ResultCallback&lt;LocationSettingsResult&gt;() {
              @Override
              public void onResult(LocationSettingsResult result) {
                  final Status status = result.getStatus();
                  final LocationSettingsStates state = result.getLocationSettingsStates();
                  switch (status.getStatusCode()) {
                      case LocationSettingsStatusCodes.SUCCESS:
                          // All location settings are satisfied. The client can initialize location
                          // requests here.
                          message.arg1 = 1;
                          break;
                      case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                          message.arg1 = 0;
                          // Location settings are not satisfied. But could be fixed by showing the user
                          // a dialog.
  //                        try {
  //                            // Show the dialog by calling startResolutionForResult(),
  //                            // and check the result in onActivityResult().
  //                            //status.startResolutionForResult(activity, 1000);
  //                        } catch (IntentSender.SendIntentException ignored) {}
                          break;
                      case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                          // Location settings are not satisfied. However, we have no way to fix the
                          // settings so we won't show the dialog.
                          message.arg1 = 0;
                          break;
                  }
              }
          });
      }
  
      //To tell OS to give preference to this network
      private void assignHighestPriority(WifiConfiguration config) {
          List&lt;WifiConfiguration&gt; configuredNetworks = wifi.getConfiguredNetworks();
          if (configuredNetworks != null) {
              for (WifiConfiguration existingConfig : configuredNetworks) {
                  if (config.priority &lt;= existingConfig.priority) {
                      config.priority = existingConfig.priority + 1;
                  }
              }
          }
      }
  
  
      /////
  
  
  }
  </code></pre>