How to Connect Android Apps to Wi-Fi Without Internet

Android - Connecting your app to a Wi-Fi connection without internet
Nov 10 2020 · 3 min read

Introduction 

This post shows steps to programmatically connect your app to wifi. We will use Wifi Manager to manage wi-fi connectivity and Connectivity Manager to handle network state and connectivity changes.

Stop the habit of wishful thinking and start the habit of thoughtful wishes with Justly.

Let's get started!

First and foremost, add permissions in your manifest file. These 4 permissions are required to make changes in your device network connectivity.

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

Setup configuration to connect one specific wifi using WifiConfiguration.

public static WifiConfiguration buildWifiConfig() {
    WifiConfiguration config = new WifiConfiguration();
    config.SSID = "\"networkSSID\"";
    config.wepKeys[0] = "\"networkPassword\"";
    // have to set a very high number in order to ensure that          //Android doesn't immediately drop this connection and reconnect to //the a different AP.
    config.priority = 999999;
    return config;
}

To connect to the Wi-Fi network, register a BroadcastReceiver that listens for WifiManager.NETWORK_STATE_CHANGED_ACTION

public class WifiChangeBroadcastReceiver extends BroadcastReceiver {
  private WifiChangeBroadcastListener listener;
public WifiChangeBroadcastReceiver(WifiChangeBroadcastListener listener){
   this.listener=listener;
}
@Override
  public void onReceive(Context context, Intent intent) {
    listener.onWifiChangeBroadcastReceived(context, intent);
  }
   public interface WifiChangeBroadcastListener {
        void onWifiChangeBroadcastReceived(Context context, Intent intent);
    }
}
 

Register broadcast receiver from your activity’s onStart and don’t forget to unregister it in onStop.

private WifiChangeBroadcastReceiver wifiStateChangeReceiver;
@Override
protected void onStart() {
    super.onStart();
    wifiStateChangeReceiver = new WifiChangeBroadcastReceiver(this);
registerReceiver(wifiStateChangeReceiver,
        new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION));
}
@Override
protected void onStop() {
    super.onStop();
    unregisterReceiver(wifiStateChangeReceiver);
}

Now it is time to connect your app to wifi.

if(currentConnectionInfo.getSSID().equals(targetNetworkSSID)) {
            // we're already connected to this AP, nothing to do.
    } else {
      // If network is configured, we can obtain the network ID from // the WifiConfiguration object.
            int networkId= getIdForConfiguredNetwork("networkSSID");
            if (networkId == -1) {
                // Add network to configured network list.
                networkId = wifiManager.addNetwork(wifiConfig);
            }
      //after enableNetwork call we will receive network change broadcast.
      wifiManager.enableNetwork(networkId, true);
     }
 }
@Override
public void onWifiChangeBroadcastReceived(Context context, 
                                          Intent intent)
 {
        WifiConfiguration wifiConfig = buildWifiConfig();
        WifiInfo wifiInfo = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
        if (wifiInfo == null || wifiInfo.getSSID() == null) {
            // no WifiInfo or SSID means we're not interested.
            return;
        }
        String newlyConnectedSSID = wifiInfo.getSSID();
        if (newlyConnectedSSID.equals(wifiConfig.SSID)) {
            bindProcessToNetwork();
        }
    }
 public int getIdForConfiguredNetwork(String ssid) {
        List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks();
        for (WifiConfiguration configNetwork : configuredNetworks) {
            if (configNetwork.SSID.equals(ssid)) {
                return configNetwork.networkId;
            }
        }
        return -1;
    }

Here is our bindProcessToNetwork method to bind current process to network, this will route all network request to specific network

public void bindProcessToNetwork() {
    if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
        Network network= getNetworkObjectForCurrentWifiConnection();
        if (Build.VERSION.SDK_INT >= VERSION_CODES.M) {
            connectivityManager.bindProcessToNetwork(network);
        } else {
            ConnectivityManager.setProcessDefaultNetwork(network);
        }
    }
}
@Nullable
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public Network getNetworkObjectForCurrentWifiConnection() {
        List<Network> networks = Arrays.asList(connectivityManager.getAllNetworks());
        for (Network network : networks) {
            NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
            if (capabilities.hasTransport
                    (NetworkCapabilities.TRANSPORT_WIFI)) {
                return network;
            }
        }
        return null;
    }

Conclusion

Hurray! We just connected our app to a wifi connection which does not have internet connectivity. It’s very useful in IOT devices where devices host wifi to allow communication with other devices but it might not have internet connectivity.

You can find complete code HERE !!

Thanks for your support!

Happy coding!


radhika-s image
Radhika saliya
Android developer | Sharing knowledge of Jetpack Compose & android development


radhika-s image
Radhika saliya
Android developer | Sharing knowledge of Jetpack Compose & android development

contact-footer
Say Hello!
footer
Subscribe Here!
Follow us on
2024 Canopas Software LLP. All rights reserved.